Attention: Aacini Re: Resistor color calculator

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Gerhard
Posts: 11
Joined: 25 Oct 2021 22:01

Attention: Aacini Re: Resistor color calculator

#1 Post by Gerhard » 26 Oct 2021 00:00

@Aacini, We can use this topic for the challenge.

I suggest the following judging criteria (you can add/remove/change where required:
1. The "must" be pure batch-file and powershell. No external tools/functions allowed. (this is critical else it is cheating :D )
2. The code needs to be as short as possible, but any commentary or echo/write-host text excluded.
3. The results needs to be as accurate as possible.
4. Input methods are not relevant to judging. So no matter how you collect user info (choice, multiple inputs or single input string) This is not part of the criteria.
5. You can post your results when ready. No time given to complete.
6. For the interest of time and simplicity, we only focus on either 4 or 5 band resistors, no need to do both. You decide.

To anyone else reading this. As a fun project, Aacini and myself are doing a challenge to build a resistor resistance calculator. I will be doing powershell and Aacini batch-file. It is for fun and learning.
I am a big batch-file fan and I try and do everything I can in it before going to powershell or other external tools for most general purpose solutions. So please do not think that I am a powershell fanboy. This is just something that popped up based on some comments on StackOverFlow.

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Attention: Aacini Re: Resistor color calculator

#2 Post by Aacini » 26 Oct 2021 06:35

Ok. The post that originated this challenge is this SO question. The OP required a calculation with a percent (2 decimals) and Gerhard suggested to use PowerShell instead because "it will be way simpler than cmd (batch-file)". I don't agree and invited Gerhard to write a PS solution so we can compare it vs. my Batch-file one. So here we are! :D You are invited to opine about how "simpler" is one solution vs. the other one.

Gerhard,

I agree in all your points excepting the #3. Input data have just 4 decimals. I write my program so the output is accurate with just 2 decimals. If you want that my results be accurate with 4 decimals, please tell that. I will modify the code accordingly.

Also, additional lines inserted for clarity do not count as "long code". We cannot sacrifice clarity for brevity...

My program manage 4 band resistors and an additional one-line IF allows to also manage 5 bands. You use wichever you want.

I want to insert the additional point of don't check user input for errors, in order to keep the code simple. Good data produce good results, bad data don't...

Antonio

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Attention: Aacini Re: Resistor color calculator

#3 Post by Aacini » 26 Oct 2021 06:39

This is my Batch-file solution:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "i=0"
for %%D in (
	Black:B:1 
	browN:N:10:0.0100
	Red:R:100:0.0200 
	Orange:O:1000:0.0300
	Yellow:Y:10000:0.0400
	Green:G:100000:0.0050
	bLue:L:1000000:0.0025
	Violet:V:10000000:0.0010
	grEy:E:100000000:0.0005
	White:W:1000000000
	golD:D:10:0.0500
	Silver:S:100:0.1000
) do for /F "tokens=1-5 delims=:." %%a in ("%%D") do (
   set "colors=!colors! %%a"
   set /A "%%b=i, mult[%%b]=%%c, tol[%%b]=1%%e%%10000, i+=1"
)

echo    %colors%
echo/
echo Enter the 4- or 5-band Resistor Colors using the uppercase letters above,
set /P "band=separating them by a space: "
for /F "tokens=1-5" %%a in ("%band%") do (
   set "color3=" & set /A "color1=%%a, color2=%%b, multiplier=mult[%%c], multBand=%%c, tolerance=tol[%%d]" 
   if "%%e" neq "" set /A "color3=%%c, multiplier=mult[%%d], multBand=%%d, tolerance=tol[%%e]"
)

set /A "value=%color1%%color2%%color3%*100, percent=value*multiplier*tolerance/1000"
if %multBand% gtr 9 set /A "percent=value/multiplier*tolerance/1000"

set /A "min=value-percent, max=value+percent"
echo Minimum: %min:~0,-2%.%min:~-2%
echo Maximum: %max:~0,-2%.%max:~-2%
The resistor color code chart is here.

Antonio

Gerhard
Posts: 11
Joined: 25 Oct 2021 22:01

Re: Attention: Aacini Re: Resistor color calculator

#4 Post by Gerhard » 26 Oct 2021 07:10

Apologies, Aacini. I did not mean the decimals. Just correct data. So if a resistor is +- 1Kohm, we need to match that. Then on number of bands of the resistor to focus on, I see you already catered for 4 and 5 bands, so I will do the same. Give me a few minutes to post mine and also test yours.
Last edited by Gerhard on 26 Oct 2021 08:23, edited 1 time in total.

Gerhard
Posts: 11
Joined: 25 Oct 2021 22:01

Re: Attention: Aacini Re: Resistor color calculator

#5 Post by Gerhard » 26 Oct 2021 08:22

Ok, so I just finished this and did not do optimal testing yet, but I will edit if I find anything particularly wrong.

I have not created any decimal system to differentiate between Ohm / K-Ohm / M-Ohm. If you feel that it is something I need to do, then please do let me know.

Code: Select all

$bds = @{
	black = @(0;1;0)
	brown = @(1;10;0.01)
	red = @(2;100;0.02)
	orange = @(3;1000;0)
	yellow = @(4;10000;0)
	green = @(5;100000;0.005)
	blue = @(6;1000000;0.0025)
	violet = @(7;10000000;0.001)
	grey = @(8;100000000;0)
	white = @(9;1000000000;0)
	gold = @(0;0.1;0.05)
	silver = @(0;0.01;0.1)
}
$in = Read-Host "Enter 4 or 5 band colors in order. example: (red red green silver)";$arr = $in.Split(" ");
$cl1 = $arr[0];$cl2 = $arr[1];$mlt = $arr[2];$tol = $arr[3];$nm = (($bds[$cl1][0] * 10) + $bds[$cl2][0]) * $bds[$mlt][1]
if ( $arr[4] )
{
    $cl1 = $arr[0];$cl2 = $arr[1];$cl3 = $arr[2];$mlt = $arr[3];$tol = $arr[4];$nm =  (($bds[$cl1][0] * 100) + ($bds[$cl2][0] * 10) + $bds[$cl3][0]) * $bds[$mlt][1]
}
$prc = $nm*$bds[$tol][2];$mn = $nm-$prc;$mx = $nm + $prc
write-host "Nominal:" $nm ohms"`n"Minimum: $mn ohms"`n"Maximum: $mx ohms"`n"
Then on your batch-file. It is working, but I am seeing some results which are not 100% (maybe I am doing something wrong) but on: Red Red Green Silver I am expecting:

Code: Select all

Min: 1980000 ohm
Max: 2420000 ohm
But I am getting:

Code: Select all

Minimum: -9544.67
Maximum: 9588.67
I am using https://www.allaboutcircuits.com/tools/ ... alculator/ to verify results, the one you posted is not working for me as I am using an ad-blocker.

siberia-man
Posts: 208
Joined: 26 Dec 2013 09:28
Contact:

Re: Attention: Aacini Re: Resistor color calculator

#6 Post by siberia-man » 27 Oct 2021 03:45

@Gerhard, @Aacini

I've been interested in the challenge you both involved. I read two links:

https://www.allaboutcircuits.com/tools/ ... alculator/
https://www.allaboutcircuits.com/textbo ... lor-codes/

and found some discrepancy between those two.

From the first we can see:
Color Code Exceptions
5 Band Resistor with a 4th Band of Gold or Silver
Five band resistors with a fourth band of silver or gold form an exception, and are utilized on specific or older resistors. The first two bands represent the significant digits, the third band is a multiplication factor, the fourth band is for tolerance and the fifth band is for the temperature coefficient (ppm/K).
In the other hand, from the second one we can see that the resistors are calculated without this exception:
Brown-Green-Grey-Silver-Red Color Code
A resistor colored Brown-Green-Grey-Silver-Red would be 1.58 Ω with a tolerance of +/- 2%.

Blue-Brown-Green-Silver-Blue Color Code
A resistor colored Blue-Brown-Green-Silver-Blue would be 6.15 Ω with a tolerance of +/- 0.25%.
For example:

With no taking exception (as it's shown in the example by the second link and estimated using the calculator by the first link):

Code: Select all

Brown	- 1
Green	- 5
Grey	- 8
Silver	- 0.01 Ohm
Red	- 2 %
Brown-Green-Grey-Silver-Red = 158 * 0.01 +/- 2% = 1.58 +/- 2%
As it's expected if taking the exception:

Code: Select all

Brown	- 1
Green	- 5
Grey	- 100 MOhm
Silver	- 0.05 %
Red	- 10 ppm/C
Brown-Green-Grey-Silver-Red = 15 * 100e6 +/- 0.05% = 1500000000 +/- 0.05%
The same for "Blue-Brown-Green-Silver-Blue Color Code"

Gerhard
Posts: 11
Joined: 25 Oct 2021 22:01

Re: Attention: Aacini Re: Resistor color calculator

#7 Post by Gerhard » 27 Oct 2021 05:03

@Siberia-Man, thank you for checking up on that.

Let me find some more references that to get a conclusive result. Perhaps @Aacini and I just need to focus our results on a single source for comparison. He did provide me with his source, but I am unable to access it due to running an ad-blocker on my network at home.

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Attention: Aacini Re: Resistor color calculator

#8 Post by Aacini » 27 Oct 2021 17:31

I don't know how to read Resistor Color Codes (I am not Electronic Engineer). The original question have these lines:

Code: Select all

set /a percent=(%color1%%color2% * %multiplier%) * %tolerance%
set /a min=%color1%%color2% - %percent%
set /a max=%color1%%color2% + %percent%
So, for example, using Red-Red-Green-Silver bands we have:

Code: Select all

set /a percent=(22 * 100000) * 0.10
set /a min=22 - percent
set /a max=22 + percent
My first program use this formulae, but it is wrong...

The correct code seems to be this one:

Code: Select all

set /a value=%color1%%color2% * multiplier
set /a percent=value * tolerance
set /a min=value - percent
set /a max=value + percent
I fixed this part in the new code below. I also modified the input data so it now reads whole words instead of single letters, that is, the same method you used. I did this in order to make both codes as similar as possible, so the comparison between them be done just in the different details of both languages...

Code: Select all

@echo off
setlocal EnableDelayedExpansion

for %%D in (
	Black:0:1 
	Brown:1:10:0.0100
	Red:2:100:0.0200 
	Orange:3:1000:0.0300
	Yellow:4:10000:0.0400
	Green:5:100000:0.0050
	Blue:6:1000000:0.0025
	Violet:7:10000000:0.0010
	Grey:8:100000000:0.0005
	White:9:1000000000
	Gold:10:10:0.0500
	Silver:11:100:0.1000
) do for /F "tokens=1-5 delims=:." %%a in ("%%D") do (
   set /A "%%a=%%b, mult[%%a]=%%c, tol[%%a]=1%%e%%10000"
)

echo Enter 4 or 5 band Resistor Colors, like in:  Red Red Green Silver
set /P "band="
for /F "tokens=1-5" %%a in ("%band%") do (
   set "color3=" & set /A "color1=%%a, color2=%%b, multiplier=mult[%%c], multBand=%%c, tolerance=tol[%%d]" 
   if "%%e" neq "" set /A "color3=%%c, multiplier=mult[%%d], multBand=%%d, tolerance=tol[%%e]"
)

if %multBand% leq 9 (
   set /A "value=%color1%%color2%%color3%*multiplier"
) else (
   set /A "value=%color1%%color2%%color3%/multiplier"
)

set /A "percent=value/100*tolerance/100, min=value-percent, max=value+percent"
echo Nominal: %value%
echo Minimum: %min%
echo Maximum: %max%
You opined that both programs use the same method and this is precisely my point. You can use practically the same structure of any other language in a Batch-file and the result will be similar, excepting of course when the emulation of a non-native Batch-file feature takes too much code. The emulation of fixed-point arithmetic with 4 decimales is rather simple. This is the reason because I don't agree when someone say that "in X language it is much simpler than in a Batch file".

However...

Batch files had evolved from ancient times and they have poor definition of many operative details. This means that a Batch-file is more permisive than many modern better-defined languages. If we make good use of this poorly-defined features, we can perform certain things in a simpler way. A very simple example of this point is to exchange the value of two variables:

Code: Select all

set "var1=%var2%" & set "var2=%var1%"
This works because the way that %standard% expansion is performed. I don't know of any other programming language where this be possible (excepting perhaps assembler with its XCHG instruction)...

In the Batch-file version of the code we have here, we have this line:

Code: Select all

   set /A "value=%color1%%color2%%color3%*multiplier"
If %color3% is not defined then it is replaced by "nothing", so the same code works for both 4- and 5-band colors with no modification.

In PowerShell we can't do the same. We need to check for each variable and individually manage it, that is the "good way" to do it:

Code: Select all

$nm = (($bds[$cl1][0] * 10) + $bds[$cl2][0]) * $bds[$mlt][1]
if ( $arr[4] ) {
    $nm =  (($bds[$cl1][0] * 100) + ($bds[$cl2][0] * 10) + $bds[$cl3][0]) * $bds[$mlt][1]
}
So, in this particular line, a Batch-file is simpler than the PowerShell equivalent...

Antonio

Gerhard
Posts: 11
Joined: 25 Oct 2021 22:01

Re: Attention: Aacini Re: Resistor color calculator

#9 Post by Gerhard » 27 Oct 2021 23:46

Thanks Aacini. Your code is now providing the correct values and matches my powershell results.

I do get what you are saying about the powershell option not being a "simpler" solution than batch. My comment around the powershell solution was maybe made without looking at the requirements of the topic. So let me try and clarify my intentions with that particular comment.

Given any situation where decimals are used, unlike the current situation, powershell can handle floating point with ease. In the case of the resistor color code solution, you can achieve what you with this part

Code: Select all

do for /F "tokens=1-5 delims=:." %%a in ("%%D") do (
   echo %%a %%b 1%%e%%10000
   set /A "%%a=%%b, mult[%%a]=%%c, tol[%%a]=1%%e%%10000"
but it would have changed a bit if the tolerance value was something like 1.010. With cmd you would therefore need to cater for both sides of the value, should you want to calculate 2200000*1.010

In normal floating point circumstances, using powershell would be optimal as the calculartion functions are built in. Given the example of 1.010 you can simply do:

2200000*1.010
with result:

2222000

but, all that said, that is not relevant to the particular topic of the resistor resistance calculations. So I will therefore admit that for this instance, and many like it, powershell is not necessarily a simpler option.

Thank you for taking part of this. It is always fun to share and take opinions as well as learning in the process.

Suggestion, seeing as we have spent the time on this. Perhaps we can undelete the topic on SO and we can both post our code. I cannot see why not seeing as we have spent all this time on creating something they requested?

PS!! One thing on the last comment you made on my powershell code. The real reason for that if statement is really more because of the shift in the color code band numbers for 4 vs 5 bands. I am sure I could have improved on that, but I just added that as a last minute thing when you posted your code, but that will not really make the powershell option a "simpler" solution either.

Post Reply