mersenneforum.org

mersenneforum.org (https://www.mersenneforum.org/index.php)
-   Programming (https://www.mersenneforum.org/forumdisplay.php?f=29)
-   -   vbscript help (https://www.mersenneforum.org/showthread.php?t=10945)

IronBits 2008-11-10 02:33

vbscript help
 
I'm hoping someone here knows enough about vbs to help me.
I have this script that works ok, but I'm sure it's not optimal and would appreciate any assistance to make it better.
Yes, I'm a newbie at it, and just trying to learn it. Try not to laugh too hard :wink:

First, the .txt file I'm parsing is Unix based ... cr/lf I think chars at the end of each line...

user=MyUserName is my Name
[2008/08/11 06:04:17]
305*2^587594-1 is not prime. Res64: D7E974A6678F50AD Time : 956.0 sec.
user=User Name 1
[2008/08/11 06:04:29]
301*2^587635-1 is prime! Time : 515.0 sec.
user=UserName2
[2008/08/11 06:04:34]
395*2^587644-1 is not prime. Res64: 64EDC1DAF0150DCD Time : 367.0 sec.

And now the in efficient code that does the work.

[code]
Option Explicit

Const ForReading = 1, ForWriting = 2, ForAppending = 8

Dim oFSO, oInFile, oOutFile
Dim str_Input, str_Output, str_CurrentLine, str_CSV, MyArray, MyLine, UserName
Dim MyDate, MyMO, MyDD, MyYY, MyDay, MyAMPM
Dim MyTIME, MyHH, MyMM, MySS
Dim MyK, MyP, MyN, MyDATA, MyRES, MyT, MyD

' the path to the input and output file
str_Input = "c:\Results.txt"
str_Output = "c:\Results.csv"

str_CSV=""

Set oFSO = CreateObject("Scripting.FileSystemObject")

' If the file exists
If oFSO.FileExists(str_Input) Then

' open the text file for input
Set oInFile = oFSO.OpenTextFile(str_Input)

' create the csv file for output
Set oOutFile = oFSO.CreateTextFile(str_Output,True)

' for each line in the input file
Do While Not oInFile.AtEndOfStream

' read the line

str_CurrentLine = oInFile.ReadLine()
str_CurrentLine = Replace(str_CurrentLine, Chr(13), "")
str_CurrentLine = Replace(str_CurrentLine, Chr(10), "")

if Left(str_CurrentLine,5) = "user=" Then
MyArray = Split(str_CurrentLine,"=",-1,1)
UserName = MyArray(1)
End If

if Left(str_CurrentLine,1) = "[" Then
'[08/11/2008 06:55:34 AM]
MyLine = Split(str_CurrentLine," ", -1, 1 )
MyDay = Split(MyLine(0),"/", -1 ,1 )
MyMO = Replace( MyDay(0), "[", "" )
MyDD = MyDay(1)
MyYY = MyDay(2)
MyTime = Split(MyLine(1),":")
MyHH = MyTime(0)
MyMM = MyTime(1)
MySS = MyTime(2)
MyAMPM = Replace( MyLine(2), "]", "" )
if MyAMPM = "AM" and MyHH = "12" Then MyHH = "00" End If
If MyAMPM = "PM" and MYHH = "00" Then MyHH = "12" End If
If MyAMPM = "PM" and MYHH = "01" Then MyHH = "13" End If
If MyAMPM = "PM" and MYHH = "02" Then MyHH = "14" End If
If MyAMPM = "PM" and MYHH = "03" Then MyHH = "15" End If
If MyAMPM = "PM" and MYHH = "04" Then MyHH = "16" End If
If MyAMPM = "PM" and MYHH = "05" Then MyHH = "17" End If
If MyAMPM = "PM" and MYHH = "06" Then MyHH = "18" End If
If MyAMPM = "PM" and MYHH = "07" Then MyHH = "19" End If
If MyAMPM = "PM" and MYHH = "08" Then MyHH = "20" End If
If MyAMPM = "PM" and MYHH = "09" Then MyHH = "21" End If
If MyAMPM = "PM" and MYHH = "10" Then MyHH = "22" End If
If MyAMPM = "PM" and MYHH = "11" Then MyHH = "23" End If
End If
' 0 1 2 3 4 5 6 7 8 9
' 305*2^587594-1 is not prime. Res64: D7E974A6678F50AD Time : 956.0 sec.

If inStr(1,str_CurrentLine,"not prime.") Then
MyDATA = Split(str_CurrentLine," ",-1,1)
MyK = Split(MyDATA(0),"*",-1,1) ' 305 * 2 ^ 587594 - 1
MyP = Split(MyK(1),"^",-1,1) ' 2
MyN = Split(MyP(1),"-",-1,1) ' 587594
MyD = MyN(1) ' 1
MyRES = MyDATA(6) ' residue
MyT = MyDATA(10) ' Time
Wscript.echo "user=" & UserName
Wscript.echo "[" & MyYY & "/" & MyMO & "/" & MyDD & " " & MyHH & ":" & MyMM & ":" & MySS & "]"
Wscript.echo MyK(0) & " " & "*" & " " & MyP(0) & " " & "^" & " " & MyN(0) & " " & "-" & " " & MyD & " " & MyRES & " " & MyT
' str_CSV = "user=" & UserName & VBCrLf & "[" & MyYY & "/" & MyMO & "/" & MyDD & " " & MyHH & ":" & MyMM & ":" & MySS & "]" & VBCrLf & Str_CurrentLine
' Wscript.echo str_CSV
' output the data to the csv file
oOutFile.WriteLine(str_CSV)
End If

' 301*2^587635-1 is prime! Time : 515.0 sec.
If inStr(1,str_CurrentLine,"prime!") Then
MyDATA = Split(str_CurrentLine," ",-1,1)
MyK = Split(MyDATA(0),"*",-1,1) ' 305 * 2 ^ 587594 - 1
MyP = Split(MyK(1),"^",-1,1) ' 2
MyN = Split(MyP(1),"-",-1,1) ' 587594
MyD = MyN(1) ' 1
MyT = MyDATA(6) ' Time
Wscript.echo "user=" & UserName
Wscript.echo "[" & MyYY & "/" & MyMO & "/" & MyDD & " " & MyHH & ":" & MyMM & ":" & MySS & "]"
Wscript.echo MyK(0) & " " & "*" & " " & MyP(0) & " " & "^" & " " & MyN(0) & " " & "-" & " " & MyD & " " & " " & MyT
' str_CSV = "user=" & UserName & VBCrLf & "[" & MyYY & "/" & MyMO & "/" & MyDD & " " & MyHH & ":" & MyMM & ":" & MySS & "]" & VBCrLf & Str_CurrentLine
' Wscript.echo str_CSV
oOutFile.WriteLine(str_CSV)
' MsgBox "Prime Found!" & VBCr & "by: " & UserName & VbCr & Str_CurrentLine
End If

str_CSV=""

LOOP

' Close the input and output file
oInFile.Close
oOutFile.Close

' Finished and exit
End IF

' Tidy up
Set oFSO = Nothing

[/code]

starrynte 2008-11-10 03:15

i don't know vbscript, but some vague ideas on how i would do it in java is:
0. start from beginning of file
1. read the next character (in java it's actually: read the next byte, then cast it into a char, but thats not relevant)

assuming the possible "types" of lines are all included in your example,
[quote]
user=MyUserName is my Name
[2008/08/11 06:04:17]
305*2^587594-1 is not prime. Res64: D7E974A6678F50AD Time : 956.0 sec.
user=User Name 1
[2008/08/11 06:04:29]
301*2^587635-1 is prime! Time : 515.0 sec.
user=UserName2
[2008/08/11 06:04:34]
395*2^587644-1 is not prime. Res64: 64EDC1DAF0150DCD Time : 367.0 sec.
[/quote]2. if the character is a u , go to step 3. if the character is a [ , go to step 4. else, go to step 5.
3. (this is a user line) continue reading until the character is = . print "The user is ". then, continue reading, but print the character on the same line as you read it. if the character is a new line, print it, then go back to step 1. go back to step 1
4. (this is a date line) continue reading, output the characters as read, except when the character read is ] . then, read the next character which should be a newline, and go back to step 1
5. (this is a result line. read characters, do what you want with it. when newline character is read, go back to step 1 if not end of file)

this can possibly be modified to fit vbs and your purposes, i don't know vbs so i can't look at your code

IronBits 2008-11-10 06:11

Good ideas to think about.
What I was hoping for is to make it faster.
To do that, I'm thinking nested splits or a regex to do less coding to achieve the same thing, or just other coding ideas like you mentioned.
I wouldn't think walking down a long string would be faster than grabbing larger chucks of the string.
I was hoping for a way to split a line with multiple characters, but I don't think that's doable..
:cheers:

axn 2008-11-10 15:50

[QUOTE=IronBits;148598]What I was hoping for is to make it faster.[/QUOTE]

:huh: Just how slow is it?? I would've thought that the bottleneck would be the raw IO speed -- as in how fast you can read and write the files. Now matter how "slow" your computation logic is, it should be just a fraction of the total IO time.

Have you timed the screen output version (Wscript.echo) vs direct file output version (commented in the posted code)?

IronBits 2008-11-11 01:42

Faster is the wrong word to use. I am looking for a more optimized way to do the same work, so that I can learn to write better code in the future.
The time it takes to rip through 60,000 lines of data is under a minute, so time is not as important as writing more efficient code at this point.
Appreciate the feedback, comments and suggestions.

Patrick123 2008-11-11 06:02

The most obvious piece of code that can be optimized is

[CODE]
If MyAMPM = "PM" and MYHH = "00" Then MyHH = "12" End If
If MyAMPM = "PM" and MYHH = "01" Then MyHH = "13" End If
If MyAMPM = "PM" and MYHH = "02" Then MyHH = "14" End If
If MyAMPM = "PM" and MYHH = "03" Then MyHH = "15" End If
If MyAMPM = "PM" and MYHH = "04" Then MyHH = "16" End If
If MyAMPM = "PM" and MYHH = "05" Then MyHH = "17" End If
If MyAMPM = "PM" and MYHH = "06" Then MyHH = "18" End If
If MyAMPM = "PM" and MYHH = "07" Then MyHH = "19" End If
If MyAMPM = "PM" and MYHH = "08" Then MyHH = "20" End If
If MyAMPM = "PM" and MYHH = "09" Then MyHH = "21" End If
If MyAMPM = "PM" and MYHH = "10" Then MyHH = "22" End If
If MyAMPM = "PM" and MYHH = "11" Then MyHH = "23" End If
[/CODE]

This can be changed to:

[CODE]
If MyAMPM = "PM" Then
MyHH = Str(Val(MyHH)+12)
End If
[/CODE]

Regards
Patrick

Patrick123 2008-11-11 06:16

The other option I would do is to change your construct:

[CODE]
if Left(str_CurrentLine,5) = "user=" Then
....
End if

if Left(str_CurrentLine,1) = "[" Then
....
End if

If inStr(1,str_CurrentLine,"not prime.") Then
....
End if

If inStr(1,str_CurrentLine,"prime!") Then
....
End if

[/CODE]

With the construct:

[CODE]

if Left(str_CurrentLine,5) = "user=" Then
....

ElseIf Left(str_CurrentLine,1) = "[" Then
....

ElseIf inStr(1,str_CurrentLine,"not prime.") Then
....

ElseIf inStr(1,str_CurrentLine,"prime!") Then
....
End if

[/CODE]

This would ensure you don't carry on checking the line once one of the conditions has been met.

Regards
Patrick

IronBits 2008-11-11 14:30

Schweet! :smile:
Excellent suggestions.
I had one problem, took me a bit to figure it out, but here is the code change to your code change suggestion.

If MyAMPM = "PM" and MyHH <> "12" Then MyHH = MyHH+12 End If

If I used your suggestion of
If MyAMPM = "PM" Then MyHH = Str(Val(MyHH)+12) End If

I got "val is undefined" ...

Seems they left the keyword Val out of Visual Basic Scripting :(
[url]http://www.htmlgoodies.com/beyond/asp/vbs-ref/article.php/3458631[/url]

As soon as I finish up the output for the csv file, I'll repost my code for final approval :smile:

axn 2008-11-11 14:50

[QUOTE=IronBits;148839]I got "val is undefined" ...[/QUOTE]
Use CInt or CLng. (And CStr for converting to String)

IronBits 2008-11-11 18:28

Thanks for the Cint suggestion. I'll look into it further.

For now, here is my 'final' code on parsing Results.txt produced from llrnet servers.

I'm sure there are some optimizations that could be done, so if you see any, appreciate any tips. :smile:
All my filenames that I parse end with .org.txt so I'm making copies of the original files to create the .txt and .csv files.
I suppose if someone passed the filename Results.txt as an argument, this would fail...

[code]
Option Explicit

Const ForReading = 1, ForWriting = 2, ForAppending = 8

Dim oFSO, oInFile, oOutFiletxt,oOutFilecsv
Dim str_Input, str_Output, str_OutCSV, str_CurrentLine, str_CSV, str_TXT
Dim MyArray, MyLine, UserName, Lines
Dim MyDate, MyMO, MyDD, MyYY, MyDay, MyAMPM
Dim MyTIME, MyHH, MyMM, MySS
Dim MyK, MyP, MyN, MyDATA, MyRES, MyT, MyD
Dim Team_Name, arrMyTeamName, FileName, strFileName, arrFileName
Dim argNum, argCount:argCount = Wscript.Arguments.Count

'Set objArgs = WScript.Arguments

If (argCount < 1) Then
Wscript.Echo VbCrLf & "Please supply the name of the Results file to be converted to .csv ." & VbCrLf
Wscript.Quit 1
End If

Wscript.Echo VbCrLf

strFileName = WScript.Arguments(0)
arrFileName = Split(strFileName,".",-1,1)

' the path to the input and output files
str_Input = strFileName
str_Output = arrFileName(0) & ".txt"
str_OutCSV = arrFileName(0) & ".csv"

str_CSV=""
str_TXT=""
Lines="0"

Set oFSO = CreateObject("Scripting.FileSystemObject")

' If the file exists

If oFSO.FileExists(str_Input) Then

' open the text file for input
Set oInFile = oFSO.OpenTextFile(str_Input)

' create the txt file for output
Set oOutFiletxt = oFSO.CreateTextFile(str_Output,True)

' create the csv file for output
Set oOutFilecsv = oFSO.CreateTextFile(str_OutCSV,True)

' for each line in the input file
Do While Not oInFile.AtEndOfStream

' read the line
str_CurrentLine = oInFile.ReadLine()
str_CurrentLine = Replace(str_CurrentLine, Chr(13), "")
str_CurrentLine = Replace(str_CurrentLine, Chr(10), "")
Lines = Lines+1

' do Team_User

if Left(str_CurrentLine,5) = "user=" Then
MyArray = Split(str_CurrentLine,"=",-1,1)
Team_Name = MyArray(1)
arrMyTeamName = Split(Team_Name,"_",-1,1)
if arrMyTeamName(0) = "gd" Then UserName = Team_Name End If
If arrMyTeamName(0) = "Free-DC" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "AMDUsers" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "ArsTechnica" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "XtremeSystems" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "Team_Italia" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "XGrubbersKickAss" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "Ukraine" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "Singapura" Then UserName = arrMyTeamName(1) End If
If arrMyTeamName(0) = "RaidersOfTheLostPrime" Then UserName = arrMyTeamName(1) End If
' do Date

ElseIf Left(str_CurrentLine,1) = "[" Then
'[08/11/2008 06:55:34 AM]
MyLine = Split(str_CurrentLine," ", -1, 1 )
MyDay = Split(MyLine(0),"/", -1 ,1 )
MyMO = Replace( MyDay(0), "[", "" )
MyDD = MyDay(1)
MyYY = MyDay(2)
MyTime = Split(MyLine(1),":")
MyHH = MyTime(0)
MyMM = MyTime(1)
MySS = MyTime(2)
MyAMPM = Replace( MyLine(2), "]", "" )
if MyAMPM = "AM" and MyHH = "12" Then MyHH = "00" End If
If MyAMPM = "PM" and MyHH <> "12" Then MyHH = MyHH+12 End If

'do not prime.

ElseIf inStr(1,str_CurrentLine,"not prime.") Then
MyDATA = Split(str_CurrentLine," ",-1,1)
MyK = Split(MyDATA(0),"*",-1,1) ' 305 * 2 ^ 587594 - 1
MyP = Split(MyK(1),"^",-1,1) ' 2
MyN = Split(MyP(1),"-",-1,1) ' 587594
MyD = MyN(1)
MyRES = MyDATA(6)
MyT = MyDATA(10)
str_TXT = "user=" & UserName & VBCrLf & "[" & MyYY & "/" & MyMO & "/" & MyDD & " " & MyHH & ":" & MyMM & ":" & MySS & "]" & VBCrLf & Str_CurrentLine
str_CSV = UserName & "," & MyYY & "/" & MyMO & "/" & MyDD & "," & MyHH & ":" & MyMM & ":" & MySS & "," & MyK(0) & "," & MyP(0) & "," & MyN(0) & ",-," & MyD & ",0," & MyRES & "," & MyT
' output the data to the csv and txt files
oOutFileTXT.WriteLine(str_TXT)
oOutFileCSV.WriteLine(str_CSV)
'do prime!

ElseIf inStr(1,str_CurrentLine,"prime!") Then
MyDATA = Split(str_CurrentLine," ",-1,1)
MyK = Split(MyDATA(0),"*",-1,1) ' 305 * 2 ^ 587594 - 1
MyP = Split(MyK(1),"^",-1,1) ' 2
MyN = Split(MyP(1),"-",-1,1) ' 587594
MyD = MyN(1)
MyT = MyDATA(6)
str_TXT = "user=" & UserName & VBCrLf & "[" & MyYY & "/" & MyMO & "/" & MyDD & " " & MyHH & ":" & MyMM & ":" & MySS & "]" & VBCrLf & Str_CurrentLine
'prime! - gd_barnes,11/8/2008,6:04:29,301,2,587635,-,1,1,,515
str_CSV = UserName & "," & MyYY & "/" & MyMO & "/" & MyDD & "," & MyHH & ":" & MyMM & ":" & MySS & "," & MyK(0) & "," & MyP(0) & "," & MyN(0) & ",-," & MyD & ",1," & "," & MyT
Wscript.echo str_TXT
oOutFileTXT.WriteLine(str_TXT)
oOutFileCSV.WriteLine(str_CSV)
' MsgBox "Prime Found!" & VBCr & "by: " & UserName & VbCr & Str_CurrentLine
End If

str_CSV=""
str_TXT=""

LOOP

' Close the input and output file

oInFile.Close
oOutFileTXT.Close
oOutFileCSV.Close

' Finished and exit

End IF

' Tidy up and print results

Set oFSO = Nothing

Wscript.Echo VbCrLf & "Processed " & Lines & " Lines in " & strFileName & VbCrLf

Wscript.Quit 0

[/code]

Patrick123 2008-11-12 07:21

[QUOTE=IronBits;148839]

I got "val is undefined" ...

[/QUOTE]

My apologies, I typed without testing first. In this case CInt would not be needed because your variables are variants so MyHH is implicitly cast as an integer when the 12 is added.

Regards
Patrick


All times are UTC. The time now is 19:22.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.