Thursday, July 17, 2014

Lesson 9 : Some fun

1729 is known as Hardy Ramanujam Number.  (There is a wiki article here). Reading the article all the way down, I read an interesting part that the Japanese Scientist Masahiki Fujiwara found out.

1729 –> add the numbers and you get 1+7+2+9=19

Reverse 19 and you get 91. 19x91=1729. According to him only 2 more numbers other than 1729 show this property. One is 81 and other is 1458. I decided to write a small piece of code to verify this.

for x=10 to 9999
' find the sum of numbers first
' reverse this number
' multiply it and you should get the original number
    n=x
    s=0
    while (n>0)
        s=s+(n mod 10)
        n=int(n/10)
    wend
'reverse s, call it rs
    if s<10 then
        rs=s
    else
        rs=(s mod 10) * 10 + int(s/10)
    end if
    if (s*rs = x) then
        wscript.echo x
    end if   
next

 

C:\scripts>nos.vbs //nologo
81
1458
1729

C:\scripts>

And yes there are only 3 numbers.

Monday, May 12, 2014

Lesson 8 : Solution to the question

Question was to modify the code in the last lesson, where

- the comma could be replaced by tab, for making it easy to read

- to add the columns and show the total.

In  the following code, it takes two parameters, first is csv file, and second is col. The same old file is used. The csv file first

C:\scripts\file-io>type sample.csv
abcd,12,E_123,300
bcde,13,E_124,301
cdef,14,E_125,302
efgh,15,E_126,303
ghij,16,E_127,304
hijk,17,E_128,305
lmno,18,E_129,306
C:\scripts\file-io>

The output of the program

C:\scripts\file-io>03-addcols-csv.vbs sample.csv 4 //nologo
abcd    12      E_123   300
bcde    13      E_124   301
cdef    14      E_125   302
efgh    15      E_126   303
ghij    16      E_127   304
hijk    17      E_128   305
lmno    18      E_129   306

Sum of Col 4 is 2121

And finally the code

Const ReadMode=1
dim fso
dim fstext
dim txtline
dim lines, words
dim strword
dim Oput
dim sums
oput=int(wscript.arguments(1))
set fso=CreateObject("Scripting.FileSystemObject")
set fstext=fso.OpenTextFile(wscript.arguments(0),ReadMode)
sums=0
do until fstext.AtEndOfStream
        txtline=fstext.ReadLine
        strword=split(txtline,",")
        sums=sums+int(strword(oput-1))
        txtline= Replace(txtline,",", vbTab)
        wscript.echo txtline
loop
wscript.echo " "
wscript.echo "Sum of Col " & oput & " is " & sums

What more can be done.

a. You can validate if the column selected exists and if it does exists is it a numeric value.

b. You can check if the csv file passed as a parameter exists in the first place.

Lesson 8 : Working with CSV files

The fun starts working with CSV files.  CSV files are comma separated value, files. Basically that means there are commas between the columns. So who creates them? Almost every application that creates logs, dumps performance data, configuration, etc. Before XML files became the craze CSV ruled the administrator’s world.

Below is a sample CSV file

abcd,12,E_123,300
bcde,13,E_124,301
cdef,14,E_125,302
efgh,15,E_126,303
ghij,16,E_127,304
hijk,17,E_128,305
lmno,18,E_129,306

Let us write a code that can display any column we like. If we pass the parameter 0 (zero) we get the entire file. If we pass a specific number we get that column. If we pass a number more than the columns we show the entire file.

First the code

'Show the selected coloumn

Const ReadMode=1
dim fso
dim fstext
dim txtline
dim lines, words
dim strword
dim Oput
oput=int(wscript.arguments(1))
set fso=CreateObject("Scripting.FileSystemObject")
set fstext=fso.OpenTextFile(wscript.arguments(0),ReadMode)
do until fstext.AtEndOfStream
    txtline=fstext.ReadLine
    strword=split(txtline,",")
    if oput=0 or oput>(ubound(strword)+1) then
        wscript.echo txtline
    else
        wscript.echo strword(oput-1)
    end if
loop

And now the output

C:\scripts\file-io>02-show-contents.vbs sample.csv 0 //nologo
abcd,12,E_123,300
bcde,13,E_124,301
cdef,14,E_125,302
efgh,15,E_126,303
ghij,16,E_127,304
hijk,17,E_128,305
lmno,18,E_129,306

C:\scripts\file-io>02-show-contents.vbs sample.csv 1 //nologo
abcd
bcde
cdef
efgh
ghij
hijk
lmno

C:\scripts\file-io>02-show-contents.vbs sample.csv 2 //nologo
12
13
14
15
16
17
18

C:\scripts\file-io>02-show-contents.vbs sample.csv 3 //nologo
E_123
E_124
E_125
E_126
E_127
E_128
E_129

C:\scripts\file-io>02-show-contents.vbs sample.csv 4 //nologo
300
301
302
303
304
305
306

C:\scripts\file-io>02-show-contents.vbs sample.csv 5 //nologo
abcd,12,E_123,300
bcde,13,E_124,301
cdef,14,E_125,302
efgh,15,E_126,303
ghij,16,E_127,304
hijk,17,E_128,305
lmno,18,E_129,306

C:\scripts\file-io>

Some exercises for you to try.

1. Suppose we need the sum of a column (like column 2 or 4) then modify the above code so that it works in the following way.

c:\>progname csvfile col

The output should a tab between the cols and not a csv and a sum below.

Friday, May 02, 2014

Lesson 7 : Working with Text files

In our routine as an administrator, we routinely work with text files. Let us try to understand how to work with them.

A usual logic would be

- Open the file, Loop line by line, display the contents (or process them)

Example 1:

In this example, we try to display the contents of the file that is passed as a parameter at the command line. I have not done validations and assume that a file name is already there. You can add three validations, first check if there is an argument. Second check if the file exists. Third check if it is a text file.  I have a sample file called “sample.txt” in the same folder as the program.

Const ReadMode=1
dim fso
dim fstext
dim txtline

set fso=CreateObject("Scripting.FileSystemObject")
set fstext=fso.OpenTextFile(wscript.arguments(0),ReadMode)

do until fstext.AtEndOfStream
    txtline=fstext.ReadLine
    wscript.echo txtline
loop

Let us check the output

C:\scripts\file-io>01-show-contents.vbs sample.txt //nologo
The quick fox jumped over
the lazy dog. The hare and the
turtle were friends in the forest.
Early bird gets the worm.

C:\scripts\file-io>

Let us make it more useful. At the end, let us say we want to display the total lines in this file.

Const ReadMode=1
dim fso
dim fstext
dim txtline
dim lines
lines=0
set fso=CreateObject("Scripting.FileSystemObject")
set fstext=fso.OpenTextFile(wscript.arguments(0),ReadMode)

do until fstext.AtEndOfStream
    txtline=fstext.ReadLine
    wscript.echo txtline
    lines=lines+1
loop
wscript.echo "--------------------------------------end of file"
wscript.echo "Lines in the file " & lines

  

C:\scripts\file-io>01-show-contents.vbs sample.txt //nologo
The quick fox jumped over
the lazy dog. The hare and the
turtle were friends in the forest.
Early bird gets the worm.
--------------------------------------end of file
Lines in the file 4

C:\scripts\file-io>

What if we needed the lines and words.

a. Use the split function, it splits a string and returns an array

b. use the ubound function to check how many elements are there in the array, and add 1

Const ReadMode=1
dim fso
dim fstext
dim txtline
dim lines, words
dim strword
lines=0
words=0
set fso=CreateObject("Scripting.FileSystemObject")
set fstext=fso.OpenTextFile(wscript.arguments(0),ReadMode)

do until fstext.AtEndOfStream
    txtline=fstext.ReadLine
    strword=split(txtline)
    words=words+ubound(strword) +1
    wscript.echo txtline
    lines=lines+1
loop
wscript.echo "--------------------------------------end of file"
wscript.echo "Lines in the file " & lines
wscript.echo "Number of words   " & words

Sample Output of the same file

C:\scripts\file-io>01-show-contents.vbs sample.txt //nologo
The quick fox jumped over
the lazy dog. The hare and the
turtle were friends in the forest.
Early bird gets the worm.
--------------------------------------end of file
Lines in the file 4
Number of words   23

C:\scripts\file-io>

Let us make it more complete. We do the following changes, we pass the parameter filename with a number, 1=show file, 2=show lines, 3=show words, 4=show all

Code

Const ReadMode=1
dim fso
dim fstext
dim txtline
dim lines, words
dim strword
lines=0
words=0
dim Oput
oput=int(wscript.arguments(1))
set fso=CreateObject("Scripting.FileSystemObject")
set fstext=fso.OpenTextFile(wscript.arguments(0),ReadMode)

do until fstext.AtEndOfStream
    txtline=fstext.ReadLine
    strword=split(txtline)
    words=words+ubound(strword) +1
    if oput=1 or oput=4 then
        wscript.echo txtline
    end if
    lines=lines+1
loop
if oput=1 or oput=4 then
    wscript.echo "--------------------------------------end of file"
end if
if oput=2 or oput=3 or oput=4 then
    wscript.echo "Lines in the file " & lines
end if
if oput=3 or oput=4 then
    wscript.echo "Number of words   " & words
end if

Various Runs

C:\scripts\file-io>01-show-contents.vbs sample.txt 1 //nologo
The quick fox jumped over
the lazy dog. The hare and the
turtle were friends in the forest.
Early bird gets the worm.
--------------------------------------end of file

C:\scripts\file-io>01-show-contents.vbs sample.txt 2 //nologo
Lines in the file 4

C:\scripts\file-io>01-show-contents.vbs sample.txt 3 //nologo
Lines in the file 4
Number of words   23

C:\scripts\file-io>01-show-contents.vbs sample.txt 4 //nologo
The quick fox jumped over
the lazy dog. The hare and the
turtle were friends in the forest.
Early bird gets the worm.
--------------------------------------end of file
Lines in the file 4
Number of words   23

C:\scripts\file-io>

We build more on this in the subsequent chapters.

Thursday, May 01, 2014

Lesson 6: Functions and Procedures (vbscript)

Functions and Procedures make your code modular. They help you to keep repeated statements as blocks of code that can be reused. Both functions and procedures do the same thing, except, Functions can return value. So as a good practice never let your functions have any statements to print(display) or get input from keyboard.

Let your functions take parameters and return the value. How does a function return a value? Function_name=value you want to return. Enough of theory.

This program finds the value of (a+b) squared.

(a+b)2 =a2 +2ab+b2

‘File-0105-1.vbs (this is file name I have)

Function Sq_ab(a,b)
    sq_ab=a*a + 2*a*b + b*b
End Function

Sub Print(str)
    wscript.echo str
End Sub

'Main program starts here

a=int(wscript.arguments(0))
b=int(wscript.arguments(1))
Print("The Square of (a+b) is " & Sq_ab(a,b))

Sample Output

C:\scripts>0105-1.vbs 2 3 //nologo
The Square of (a+b) is 25

C:\scripts>0105-1.vbs 7 9 //nologo
The Square of (a+b) is 256

C:\scripts>

Exercises for you.

1. Write functions for (a-b)2, a2-b2, (a+b)3 and so on

Saturday, April 19, 2014

Windows Scripting. Lesson 5. Magic Square

A magic square is one where the total of rows, columns and diagonals is the same.

Take a 3x3 magic square.

image

The Rules are pretty simple. The rule is called top-left rule.

1. Start with 1. Put it in the centre of the 1st row. So 1 is in (1,2) Row 1, Col 2.

2. Goto top left. In this case top is row 0, so top comes to the 3rd row. Left is row 1. So the next number is (3,1).

3. Continue with top left. Top of 3 is 2, left of 1 is 3rd column. So we are in (2,3).

4. Now the top left from 2,3 is 1,2. This place is occupied, you have a 1 there. So you need to go back to original location (2,3). Then come a place down but same column. So from 2,3 we come to 3,3. Put a 4 here. Continue this way.

5. In this case the totals of rows, col and diagonal is 15. Why 15?

6. We use the natural numbers 1 to 9. Sum of 1 to 9 is n(n+1)/2. In this example we have 9x10/2=45. We have 3 rows. So we get 45/3 or 15.

sub Print(str)
    wscript.echo str
end sub

' Main Program starts from here
dim x(3,3)
dim y
for a=1 to 3
    for b=1 to 3
        x(a,b)=0
    next
next

x(1,2)=1
a=1
b=2
for y=2 to 9
    olda=a
    oldb=b
    a=a-1
    b=b-1
    if a=0 then
        a=3
    end if
    if b=0 then
        b=3
    end if
    if x(a,b)>0 then
        a=olda
        b=oldb
        a=a+1
    end if
    x(a,b)=y
next
for a=1 to 3
    for b=1 to 3
        str=str & chr(9) & x(a,b)
    next
    wscript.echo str
    str=" "
next

- print procedure makes the printing easy.

- dim, defines an array. In this case it is an array 3 rows x 3 cols. Each value in the array is defined as 0. 1 is put then in the first row and second column.

- for loop rotates eight times for the eight numbers. a and b are the locations needed. We try top left, and if it is occupied (>0), then we go back to the original location and come one col down.

- the for loop then prints the 3 coloumns. Each row is formatted is by adding a tab (chr(9). When you compile and run this program, (magic3.vbs)

C:\scripts>magic3 //nologo
        6       1       8
        7       5       3
        2       9       4

C:\scripts>

 

Can we make a generic version of this program.  Where we can print for any odd number. Since vbscript does not allow to define an array with a variable, I have defined a large array (20,20) and allow to print a magic square. The beauty is you can pass the number as a parameter. If the parameter is even, then we add 1 and make it a odd number. The program is very similar to the previous program.

sub Print(str)
    wscript.echo str
end sub

sz=int(wscript.arguments(0))
if sz mod 2 = 0 then
    print "Argument Should be Odd"
    print "Changing to odd"
    sz=sz+1
end if
'sz=3
dim x(20,20)
dim y
for a=1 to sz
    for b=1 to sz
        x(a,b)=0
    next
next

x(1,(sz+1)/2)=1
a=1
b=(sz+1)/2
for y=2 to (sz * sz)
    olda=a
    oldb=b
    a=a-1
    b=b-1
    if a=0 then
        a=sz
    end if
    if b=0 then
        b=sz
    end if
    if x(a,b)>0 then
        a=olda
        b=oldb
        a=a+1
    end if
    x(a,b)=y
next
for a=1 to sz
    for b=1 to sz
        str=str & chr(9) & x(a,b)
    next
    wscript.echo str
    str=" "
next

Sample output.

C:\scripts>magicgen 5 //nologo
        15      8       1       24      17
        16      14      7       5       23
        22      20      13      6       4
        3       21      19      12      10
        9       2       25      18      11

C:\scripts>magicgen 7 //nologo
        28      19      10      1       48      39      30
        29      27      18      9       7       47      38
        37      35      26      17      8       6       46
        45      36      34      25      16      14      5
        4       44      42      33      24      15      13
        12      3       43      41      32      23      21
        20      11      2       49      40      31      22

An exercise for you. Can you use the n(n+1)/2 formula as mentioned earlier and print one line at the end of the program.

Sum of Rows/Col is _______

Like this

C:\scripts>magicgen 5 //nologo
        15      8       1       24      17
        16      14      7       5       23
        22      20      13      6       4
        3       21      19      12      10
        9       2       25      18      11
Sum of rows/col is      65

Friday, April 18, 2014

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 4–FileSystemObject Contd..

Continuing on FileSystemObject, Let us look at and example to extract the properties of a file. There are some new things introduced in this example

1. SUB. This is for a procedure. you can pass parameteres just like functions but just that you cannot return any values. I have put a simple procedure called Print, that takes a string as a parameter.

2. Parameteres.  You can pass parameteres to a vbscript. Wscript.argument, is where you can see the list.

Sub Print(x)
    wscript.echo x
end sub


set fso=CreateObject("Scripting.FileSystemObject")
set f=fso.GetFile(wscript.arguments(0))
print "Path               " & f.path
print "Date Created       " & f.datecreated
print "Date Last Accessed " & f.datelastaccessed
print "Date last modified " & f.datelastmodified
print "Drive              " & f.drivedir
print "Parent Folder      " & f.parentfolder
print "Size (Bytes)       " & f.size
print "Type of File       " & f.type

A few examples

C:\scripts>folder.vbs c:\53-Photos\ar-1.jpg
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Path                       C:\53-Photos\ar-1.jpg
Date Created          09/03/2014 19:50:08
Date Last Accessed  09/03/2014 19:50:08
Date last modified  09/03/2014 19:50:08
Drive                      c:
Parent Folder          C:\53-Photos
Size (Bytes)             66089
Type of File            JPEG Image

C:\scripts>folder folder.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Path               C:\scripts\folder.vbs
Date Created       18/04/2014 00:01:02
Date Last Accessed 18/04/2014 00:01:02
Date last modified 18/04/2014 01:06:49
Drive              C:
Parent Folder      C:\scripts
Size (Bytes)       491
Type of File       VBScript Script File

C:\scripts>

You can try an example to show the file size in MB or GB depending on the size of the file. Or may be list an output like the DIR command.

Tuesday, April 15, 2014

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 3–Objects

After the basics of variables, Selection and Iteration statements, let us do something useful in real life. We start with the first object FileSystemObject. This gives us access to the filesystem. An essential part of scripting. We may need to create files, modify content, look for their existence. The idea is to make you familiar with using objects as well.

Let us take an example

Set fs = CreateObject("Scripting.FileSystemObject")
Set dc = fs.Drives
For Each d in dc
    wscript.echo d.driveletter
Next

Save this script as fsdrives.vbs

Run it

C:\scripts>cscript fsdrives.vbs //nologo
C
D
F

C:\scripts>

I have three drives on my laptop. Your machine may have more or less. Let us understand the code.

Line 1 is creating an object of FileSystemObject type. Without this you cannot use what is in this object. An object is contains methods (functions) and variables. The variables may be simple variables or may be collections. Collections are more like an array, you can use a for loop to go through each of the items, and then access the properties of each.

fs is an instance of the FileSystemObject

fs.drives is referencing a property of the FileSystemObject

fs.drives returns a collection of drives.

To loop through it we need a for loop. dc is the drive collections we have used. You have a collections of drives. For each drive there are many properties. We are referencing one of the property called driveletter.

Let us make the above program more richer. We not only need the drive, but also want to know the capacity and free space.

' Main Code Starts here

Set fs = CreateObject("Scripting.FileSystemObject")
Set dc = fs.Drives
s=chr(10) & "Number of Drives " & dc.count
wscript.echo s
s=string(65,"-")
wscript.echo s
For Each d in dc
    s=d.driveletter & chr(9) & d.path & chr(9) & d.isready
    if d.isready then
        s=s & chr(9) & d.volumename
        s=s & chr(9) & d.filesystem
        ts=int(int(int(d.totalsize/1024)/1024)/1024) & " GB"
        s=s & chr(9) & ts
          ts=int(int(int(d.freespace/1024)/1024)/1024) & " GB"
        s=s & chr(9) & ts
          ts=int(int(int(d.availablespace/1024)/1024)/1024) & " GB"
        s=s & chr(9) & ts       
    end if
    wscript.echo s
Next

' We have explored, volumename, filesystem, totalsize, freespace
' availablespace, driveletter, path and isready properties from
' the drives collection. These values are for each drive.
' chr(9) is for tab and chr(10) is for new line
' Anything typed after single quote is a comment.
' space is shown in bytes. change to KB, MB, GB by dividing 1024

Copy and paste the code. Run it.

C:\scripts>cscript fsdrives.vbs //nologo

Number of Drives 3
-----------------------------------------------------------------
C       C:      True                  NTFS    421 GB  195 GB  195 GB
D       D:      True    LENOVO  NTFS    28 GB    19 GB    19 GB
F       F:      False

C:\scripts>

That is the output I get. Your challenge would be to fine tune the code further so that the numbers are aligned below each other. On your machine you may see more or less drives and the numbers different.

Monday, April 14, 2014

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 2–Solution Part 2

Fibonacci Series Solution

wscript.echo "Fibonacci Series"
x=1
y=1
wscript.echo 1
wscript.echo 1
for a=3 to 15
    z=x+y
    x=y
    y=z
    wscript.echo z
next

 

Output

C:\scripts>cscript fibo.vbs //nologo
Fibonacci Series
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610

 

An interesting video on Fibonacci Series can be viewed here.

Sunday, April 13, 2014

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 2–Solution

The following is the solution of the question in the last post. Printing the prime numbers between 1 and 100. This may not be the best logic, yet it gets what to be done. It is more important to develop a timely solution than an untimely one.

wscript.echo "1"
wscript.echo "2"
wscript.echo "3"
for x=5 to 100 step 2
    isprime=0
    for z=2 to x-1
        if x mod z = 0 then
            isprime=1
        end if
    next
    if isprime=0 then
        wscript.echo x
    end if
next

and the output

C:\scripts>cscript prime.vbs //nologo
1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97

Some more examples that you should try

1. List the Fibonacci series – first 15 numbers

2. Find the Square root of any number correct to 4 decimal places. (use Newton’s method)

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 2

In any programming language there are three things we need to learn at the earliest.

1. Types of variable

2. Selection Statements

3. Iteration or Loops

Since ours is a “get ready quick” course. We will only try what we think is essential.

1. Variable.

There are no types of variables. What ever you assign the variable takes that values. Unlike in other programming languages you have int, char, fload, date etc. There is nothing here. You can just put any value in any variable. The upside is variable usage is easy. Same variables can be recycled. The downside is explicit conversions are needed everytime a variable of a specific type is needed.

Assume you have a program with the following

i=5
wscript.echo i
i="Programs"
wscript.echo i

When you run it there is no error.

image

 

2. Selection statements.

Keeping it simple.

if <condn> then

<statements>

else

<statements>

randomize
i=int(rnd * 10)
wscript.echo i
if i mod 2 =0 then
    wscript.echo "Even Number"
else
    wscript.echo "Odd Number"
end if

randomize – resets the seed, so that you get a real random numbers all the time. rnd generates a random number between 0 and 0.999xxx. The int function converts the output to an integer (we don’t need the decimals). The mod is a operation to find the remainder.

The above program prints either even or odd depending on the random number. In the example the program is saved as third.vbs

C:\scripts>cscript third.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

7
Odd Number

C:\scripts>

C:\scripts>cscript third.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

1
Odd Number

C:\scripts>third
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

0
Even Number

C:\scripts>cscript third.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

6
Even Number

C:\scripts>

3. Iteration or Loops

The most convenient loop is the for – next.

An example

wscript.echo "Program 2"
for i=1 to 5
        wscript.echo i
next
wscript.echo "Random Numbers"
for i = 5 to 1 step -1
        randomize
        intnum=rnd
        wscript.echo int(intnum*10)
next

 

A simple program the prints, from 1 to 5. And then random numbers between 0 and 9.

Program 2
1
2
3
4
5
Random Numbers
1
0
8
2
0

Try this exercise.

Print the first 100 prime numbers.

use the concepts learnt.

Friday, April 04, 2014

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 1

Windows Scripting (the normal shell) for Ex VB Programmers - Lesson 1

Good if you know the old Visual Basic

1. How to write your first script. (lets call this as first.vbs)

1. run cmd.exe

2. create a folder called c:\scripts

3. run notepad first.vbs

clip_image002

4. Save and run this file as follows

clip_image004

5. Try to run the file without using cscript and see what you get

clip_image006

6. This is because by default vbs files are executed using wscript

7. what if you wanted to change the default. Do the following

clip_image008

8. What if you wanted to change back the default to wscript

wscript //H:wscript

-----------------------------------------------------------------end of lesson