user1707517
user1707517

Reputation: 35

Scripting for windows

This is my first time trying scripting and I'm trying to create a small program that does a simple division and mod in a loop, and then calculates the average of the mod results. This is what I have tried in Linux .sh, but how could I make it compatible with Windows .bat? Your help is very appreciated.

echo "enter first number:"
read first_num
echo “enter second number:”
read second_num
while [ first_num && second_num != 999 ]
do
    if [ second_num != 0 ]; then
        echo "Enter first number:"
        read first_num
        echo"Enter second number:"
        read second_num
        echo first_num "/" second_num "=" $((first_num / second_ num)) >> file.txt
    else
        echo "ERROR. Cannot divide by 0. Enter another number:"    
    fi
done
if [ first_num == 999 || second_num == 999 ]; then
   echo "You have exited the loop."
fi

#Mod 5 of numbers 1-100:
for i in {1...100}
do
    result=$((i % 5))
    echo i + "%5=" + result >> file.txt
done

#Average of results:
int sum=0
for (( i=1; i<101; i=i+1 ))
do    
    sum=sum+$((i % 5))
    average=$((sum/100))
    echo average
    echo average >> file.txt
done

Upvotes: 0

Views: 302

Answers (2)

Batcher
Batcher

Reputation: 167

Hope you're looking for this:

@echo off
setlocal enabledelayedexpansion
> file.txt type nul
:loopInput
echo enter first number:
set /p first_num=
echo enter second number:
set /p second_num=

if !first_num! neq 0 (
    if !second_num! neq 999 (
        if !second_num! equ 0 (
            echo ERROR. Cannot divide by 0. Enter another number:
            goto loopInput
        )
        goto loopDiv
    )
)
goto :skipDiv

:loopDiv
set /a division=first_num/second_num

>> file.txt echo !first_num! / !second_num! = !division!
goto loopInput

:skipDiv
echo You have exited the div loop.

>> file.txt echo Mod 5 of numbers 1-100:
for /l %%a in (1,1,100) do (
    set /a mod=%%a%%5
    >> file.txt echo %%a %% 5 = !mod!
)

set sum=0
for /l %%a in (1,1,100) do (
    set /a sum+=%%a%%5
)
set /a average=sum/100
>> file.txt echo Average of results: !average!

Upvotes: 0

Magoo
Magoo

Reputation: 80023

echo "enter first number:"
read first_num

becomes set /p first_num="Enter first number "

while [ first_num && second_num != 999 ]

don't have a WHILE - have to wire it. Think clubs and rocks.

:loop
if %first_num%==999 goto endloop
if %second_num%==999 goto endloop

...

goto loop
:endloop

:name is a label, %var% retrieves contents of var - is always a string enclose in quotes if the string includes spaces.

if [ second_num != 0 ]; then

translated is

if NOT %second_num%==0 ( ...things... ) else (...other things...)

or, of course

if %second_num%==0 ( ...other things... ) else (...things...)

Quirk: (one of many) : the first open-parenthesis MUST occur on the same physical line as the IF and the ELSE must be on the same physical line as the ) of the on-true statemet sequence.

echo first_num "/" second_num "=" $((first_num / second_ num)) >> file.txt

Can't do a calculation in an echo

set /a result=(first_num / second_ num)

OR

set /a result=(%first_num% / %second_ num%)

SET /A applies the results of an arithmetic expression - later addition and more C-like semantics

then

echo %first_num% / %second_num% = %result% >> file.txt

purely stringing the elements together.

Next there is a small problem. During the parsing process, any %var% is replaced by its PARSE-TIME value and THEN the line is executed. Consequently, the ECHO line above would show the values as they stood when the IF statement was entered, not after the calculations.

Two cures:

You can use SETLOCAL ENABLEDELATEDEXPANSION to switch the interpreter mode. In DELAYEDEXPANSION mode, !var! may be used to retrieve the RUN-TIME value of var. A SETLOCAL is terminated by an ENDLOCAL or by reaching END-OF-FILE in the same context. Any environment changes after a SETLOCAL are undone by an ENDLOCAL which is why it's often performed immediately after the @echo off - keeps the environment clean.

second cure is to use a subroutine. CALL :SUB (the colon means 'internal subroutine - start label is in this batchfile'. Omitting it means 'this is an external executable') The CALL creates a new context, copying the then-existing environment variables, so

:sub
echo %first_num% / %second_num% = %result% >> file.txt
goto :eof

will display the variables from the environment as it stood when a CALL :SUB was executed. Note that GOTO :EOF (the colon is REQUIRED means 'go to physical end-of-file' - the label EOF should not be declared...

(beware also flow-through to subroutines normally placed at the end of batchfiles. A judicious GOTO :EOF ensures that flow-through does not occur...

#Mod 5 of numbers 1-100:

The comments indicator is officially REM

rem Mod 5 of numbers 1-100:

BUT

::Mod 5 of numbers 1-100:

is often used as it's easier to type BUT since it's actually a misuse of a label, it is actually a label, and labels can't be used in a compound statement, you you can't use it within the parentheses of IF ... (...) else (...) or FOR...DO (...)

for i in {1...100}

becomes

for /L %%i in (1,1,100) do (

The metavariable %%i IS case-sensitive and a single character. in a FOR /L the elements are (start,step,end) - see FOR /? from the prompt (or generally command /? from the prompt) for docco...

result=$((i % 5))

becomes

set /a result=%%i %% 5

/a because the RHS is an arithmetic expression to be evaluated; %% 5 because % escapes %, the space is irrelevant and the processor needs to know that the MOD operator % is being used, not %5 (the fifth command-line argument)

int sum=0

No such thing as types; all environment variables are strings and only interpreted as integers by the set /a statement

so - that's about all there is to it...

Upvotes: 3

Related Questions