The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

BabaG (16) [Avatar] Offline
#1
this line doesn't work and gives an error that a method cannot be invoked because
[system.string] doesn't have something like op.subtraction:

$bri_opn = ($BriCtr - $BriInc)

but this line seems ok and i can't figure out why:

$blu_opn = ($BluCtr - $BluInc)

of several lines like this, all just about identical, the blu one is the only one that
doesn't complain. other lines involving addition seem to get through ok:

$bri_cls = ($BriCtr + $BriInc)

also tried:

bri_opn = ([int]$BriCtr - [int]$BriInc)

but that gave the error that bri_opn was not recognized as a cmdlet.

if this adds anything, $BriCtr and $BriInc are getting their values by
way of a get-content call to a text file in which each line carries a
value between -100 and 100.

$BriCtr = $ScriptVariable[70]
$BriInc = $ScriptVariable[71]

what have i got wrong here? please help.

thanks,
BabaG
brucepay (155) [Avatar] Offline
#2
Re: system.string problem with subtraction
String types don't support the subtraction operation. However, if the operands all in an expression look like numbers, then a numeric conversion can be performed. So

PS (3) > "a123" - 4
Method invocation failed because [System.String] doesn't contain a method named 'op_Subtraction'.
At line:1 char:9
+ "a123" - <<<< 4

results in an error but

PS (4) > "123" - 4
119
PS (5) >

You'll need to look at the data to see why strings are valid numbers. I suggest either adding a Write-Host before the statements that fail along the lines of

Write-Host "BriCtr = '$BriCtr' Brilnc = '$BriInc'"

which should show you the values of the variables.

The reason that

bri_opn = ([int]$BriCtr - [int]$BriInc)

is failing is that you're missing the '$' before bri_open. If you write

$bri_opn = ([int]$BriCtr - [int]$BriInc)

instead, you shouldn't get an error.

-bruce
BabaG (16) [Avatar] Offline
#3
Re: system.string problem with subtraction
the value of $briCtr is 80 and the value of $BriInc is 10.
BabaG (16) [Avatar] Offline
#4
Re: system.string problem with subtraction
just tried the []int thing ang, while i don't get an error with it, if the value
in $BriInc is something like 1.2, then its value is changed to 1. how
would i perform this subtraction while preserving potentially fractional
values?

thanks,
BabaG
BabaG (16) [Avatar] Offline
#5
Re: system.string problem with subtraction
or what if bot values are fractional as in:

$BriCtr = 1.5
$BriInc = .2

how would i perform simple math on those? that's all
i was trying to do. they should return a result of :

$bri_opn = 1.3
brucepay (155) [Avatar] Offline
#6
Re: system.string problem with subtraction
The core of this task is to read strings from a text file and have them interpreted as numbers. While this is easy to do in PowerShell you need to specify what kind of numbers you want them to be. If you specify [int], then the numbers will be rounded to integers. If you want them to be double-precision floating point numbers, then use [double]. Let's look at a simple example. We'll assign a string containing 4 numbers to a variable.

PS (12) > $s = "1 2 3.3 4"

This string contains a mix of integer and floating-point numbers. Let's split the string and then convert each element of the resulting array into an integer:

PS (13) > [int[]] $s.Split()
1
2
3
4

We can see that because we specified [int], 3.3 has been rounded down to 3. Now let's do this again, but using a [double[]] cast this time:

PS (14) > [double[]] $s.Split()
1
2
3.3
4
PS (15) >

Now 3.3 remains as 3.3 however all of the other numbers are also double-precision floats.

As an aside, at one point we had considered only supporting a single numeric type: double. A number of scripting languages do this because having a single numeric type simplifies most things and on modern processor architectures, integer arithmetic is not much faster than floating point (if at all). However, as we expanded our interoperation with .NET it became clear that this wouldn't be sufficient for all of the scenarios we wanted to cover. We had to eventually support all of the numeric types supported by .NET.

And now, one last variation on this exercise: instead of an array where everything is the same type, we want to split the string directly into a structure with each element converted to a distinct type. We can do this with a hashtable and multiple assignment as shown:

PS (15) > $f = @{}
PS (16) > [int] $f.a, [int] $f.b, [double] $f.c, [int] $f.d = $s.split()
PS (17) > $f

Name Value
---- -----
a 1
b 2
d 4
c 3.3

In this example, each string is converted to the desired type and then an element is added to the hashtable to hold the converted value.

-bruce
BabaG (16) [Avatar] Offline
#7
Re: system.string problem with subtraction
my script gets its values from the text file like this:

$BriCtr = $ScriptVariable[70]
$BriInc = $ScriptVariable[71]
$ConCtr = $ScriptVariable[72]
$ConInc = $ScriptVariable[73]
$GamCtr = $ScriptVariable[74]
$GamInc = $ScriptVariable[75]

$RedCtr = $ScriptVariable[76]
$RedInc = $ScriptVariable[77]
$GrnCtr = $ScriptVariable[78]
$GrnInc = $ScriptVariable[79]
$BluCtr = $ScriptVariable[80]
$BluInc = $ScriptVariable[81]

could i do this:

[double]$BriCtr = $ScriptVariable[70]
[double]$BriInc = $ScriptVariable[71]
[double]$ConCtr = $ScriptVariable[72]
[double]$ConInc = $ScriptVariable[73]
[double]$GamCtr = $ScriptVariable[74]
[double]$GamInc = $ScriptVariable[75]

[double]$RedCtr = $ScriptVariable[76]
[double]$RedInc = $ScriptVariable[77]
[double]$GrnCtr = $ScriptVariable[78]
[double]$GrnInc = $ScriptVariable[79]
[double]$BluCtr = $ScriptVariable[80]
[double]$BluInc = $ScriptVariable[81]

$bri_opn = ($BriCtr - $BriInc)
$bri_cls = ($BriCtr + $BriInc)
$con_opn = ($ConCtr - $ConInc)
$con_cls = ($ConCtr + $ConInc)
$gam_opn = ($GamCtr - $GamInc)
$gam_cls = ($GamCtr + $GamInc)
$red_opn = ($RedCtr - $RedInc)
$red_cls = ($RedCtr + $RedInc)
$grn_opn = ($GrnCtr - $GrnInc)
$grn_cls = ($GrnCtr + $GrnInc)
$blu_opn = ($BluCtr - $BluInc)
$blu_cls = ($BluCtr + $BluInc)

to avoid having to do this:

$bri_opn = ([double]$BriCtr - [double]$BriInc)
$bri_cls = ([double]$BriCtr + [double]$BriInc)
$con_opn = ([double]$ConCtr - [double]$ConInc)
$con_cls = ([double]$ConCtr + [double]$ConInc)
$gam_opn = ([double]$GamCtr - [double]$GamInc)
$gam_cls = ([double]$GamCtr + [double]$GamInc)

$red_opn = ([double]$RedCtr - [double]$RedInc)
$red_cls = ([double]$RedCtr + [double]$RedInc)
$grn_opn = ([double]$GrnCtr - [double]$GrnInc)
$grn_cls = ([double]$GrnCtr + [double]$GrnInc)
$blu_opn = ([double]$BluCtr - [double]$BluInc)
$blu_cls = ([double]$BluCtr + [double]$BluInc)

in other words, will the [double] definition carry over, or must
i keep specifying it?

thanks,
BabaG
brucepay (155) [Avatar] Offline
#8
Re: system.string problem with subtraction
Sure - this will work fine. You're constraining the variables to only contain doubles. If you assign an [int] or a string, it will be converted into a double automatically.

PS (1) > [double] $x = "123"
PS (2) > $x.gettype().fullname
System.Double
PS (3) > $x = 123

and if you try to assign something for which there is no defined conversion

PS (4) > $x="abc"
Cannot convert value "abc" to type "System.Double". Error: "Input string was not in a correct
format."
At line:1 char:3
+ $x <<<< ="abc"
PS (5) >

you'll get an error as shown above.

-bruce
BabaG (16) [Avatar] Offline
#9
Re: system.string problem with subtraction
cool. thanks bruce.