How to correctly round numbers in PowerShell - powershell

As the title suggest i'm expiriencing some issues with rounding numbers. My Script currently looks like this:
[uint16]$Product1 = Read-Host "Enter the price of your product: "
...
#$TotalProducts contains the Value from all products together
Write-Host "You spent an amount of $TotalProducts for todays shopping."
I want the programm to round the numbers so the total isn't some ridiculous long number. It does work but after i calculated it manually i saw that the programm calculated something else.
The problem here is that the programm rounds for example 122.50 to 122 instead of 123.
I tried using the following syntax but without success:
[math]::Round($Product1)[System.Midpoint.Rounding]::AwayFromZero) = Read-Host "Enter the price of your product: "
Am i trying the right thing but i'm butchering the syntax or am i completly wrong with this approach?

Read-Host returns a string.
You should read first, then round the number.
$Product1 = Read-Host "Enter the price of your product: "
$RoundedNumber = [math]::Round($Product1, [System.MidpointRounding]::AwayFromZero)
You now have your rounded value in $RoundedNumber.

Related

Email addresses not showing in query when using LIKE '_#_%' - POSTGRE SQL

I'm cleaning some user data and am trying to find any emails that were input into the "First Name" column. Ideally, I would run a simple function and any field with "#" in it will appear.
The code I'm using to find emails is
SELECT * FROM "Import File"
WHERE "First Name" LIKE '_#_%';
I got 0 results, so I tried
WHERE "First Name" LIKE '_#_%'
OR "First Name" LIKE '__#_%'
OR "First Name" LIKE '___#_%'
and so forth.
The problem is I get a different number of results for each OR LIKE and typing it out every time will be tedious. Is there a faster function for this? (other than copy pasting)
In LIKE operations, the underscore character (_) is a single-character wildcard, whereas the percent character (%) is a multi-character wildcard.
So, to find if a column has an at symbol, you could just use this logic:
WHERE "First Name" LIKE '%#%'
...or...
WHERE POSITION('#' IN "First Name") > 0

Using the do while - infinite loop

I'm completely lost on some homework. The assignment is to use a while loop and prompt the user to enter 5 numbers. My current code looks like the following:
$x = 1
do
{
Write-Host 'Enter 5 numbers'
$x++
} while ($x -eq 5)
Seems like issue is somewhere in here ($x -eq "5"). I want PowerShell just to prompt the user for 5 random numbers then get the sum of those numbers.
A homework assignment. 8^}
Oh well... Here is one way to do this.
Yet, taking your original post and what you show in your comment. Your issue is, you are not capturing anything to sum up, nor are you using a counter to meet you entry limit.
Clear-Host
# Initial variables
$ResponseCount = 0
$Total = 0
do {
# Get a user response
$response = Read-Host "Enter 5 numbers"
# increment response counts
$ResponseCount ++
# capture and sum the entered numbers
$Total += $response
}
until ($ResponseCount -eq "5")
"`nYou have completed the required 5 entries"
"The sum of the entered numbers is: $Total"
Enter 5 numbers: 10
Enter 5 numbers: 20
Enter 5 numbers: 30
Enter 5 numbers: 40
Enter 5 numbers: 50
You have completed the required 5 entries
The sum of the entered numbers is: 150
You're correct that the issue is your condition for the loop. Currently you're telling PowerShell to run the loop while $x is exactly five. If you want your loop to properly work you will have to change the condition. You can check the PowerShell help for about_Comparison_Operators to get an idea about the operators that are available.
The other thing you need to do is read the actual values and save whatever the user enters to build the sum. There are quite a few approaches to this and the other answer has a solution for that. Also consider using more expressive variable names to make it easier for someone else to follow your code (though that's not so much an issue for this short example).

How to extract column wise data from pdf in powershell?

I want to read a .pdf file which has some data. How can I extract complete data from one specific column only using powershell? I am using iText 5 .NET (aka iTextSharp) for pdf data extraction.
This is my current code, which extracts an entire line:
$reader = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList testPOC.pdf
$page = 2
$text = [iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($reader, $page).Split([char]0x000A)
Write-Host $text[5]
Output is shown as:
ID Working Agent Assistant Name Plan Gender Year Amount Comm.% Split% Commission
4169985061 Paul E. Ted Alskd, Ols fhghslhshsl+(0sdhsk) M 12 $1,234.00 0.45% 100.00% $32.78
How can I get data only from one single column (eg. only from salary column)?
This is just a blind stab at the answer, because we don't know what type of data $text is (unless we are iTextSharp experts). You could find that out for us by entering:
$text.gettype()
From the way it shows up on output, it almost appears that it's a PSCustomObject. If so, an approach like this might work:
$text | select-object ID, Commission
I used Commission because I couldn't see Salary in your output. I added ID for the sake of context.
Note: a real answer is going to have to wait for somebody who uses iTextSharp and might know the datatype of $text without being told. That could be a long wait.

How to parse logs and mask specific characters using Powershell

I have a problem that I really hope to get some help with.
It's rather complex but I will try and keep my explanation as simple and objective as possible. In a nutshell, I have log files that contain thousands of lines. Each line consists of information like date/time, source, type and message.
In this case the message contains a variable size ...999 password that I need to mask. Basically the message looks something like this (its an ISO message):
year-day-month 00:00:00,computername,source, info,rx 0210 22222222222222333333333333333333444444444444444444444444455555008PASSWORD6666666666666666677777777777777777777777ccccdddddddddddffffffffffffff
For each line I need to zero in on password length identifier (008) do a count on it and then proceed to mask the number of following characters, which would be PASSWORD in this case. I would change it to something like XXXXXXXX instead so once done the line would look like this:
year-day-month 00:00:00,computername,source, info,rx 0210 22222222222222333333333333333333444444444444444444444444455555008XXXXXXXX6666666666666666677777777777777777777777ccccdddddddddddffffffffffffff
I honestly have no idea how to start doing this with PowerShell. I need to loop though each line in the log file, and identify the number of characters to mask.
I've kept this high level as a starting point, there are some other complexities that I hope to figure out at a later time, like the fact that there are different types of messages and depending on the type the password length starts at another character position. I might be able to build on my aforementioned question first but if anyone understands what I mean then I would appreciate some help or tips about that too.
Any help is appreciated.
Thanks!
Additional information to original post:
Firstly, thank you to everyone for your answers thus far, its been greatly appreciated. Now that I have a baseline for how your answers are being formulated based on my information I feel I need to provide some more details.
1) There was a question about whether or not the password starting position is fixed and the logic behind it.
The password position is not fixed. In an ISO message (which these are) the password, and all information in the message, is dependent on the data elements present in the message which are in turn are indicated by the bitmap. The bitmap is also part of the message. So in my case, I need to script additional logic above and beyond the answers provided to come full circle.
2) This is what I know and these are the steps I hope to accomplish with the script.
What I know:
- There are 3 different msg types that contain passwords. I've figured out where the starting position of the password is for each msg type based on the bitmap and the data elements present.
For example 0210 contains one in this case:
year-day-month 00:00:00,computername,source, info,rx 0210 22222222222222333333333333333333444444444444444444444444455555008PASSWORD6666666666666666677777777777777777777777ccccdddddddddddffffffffffffff
What I need to do:
Pass the log file to the script
For each line in the log identify if the line has a msg type that contains a password
If the message type contains a password then determine length of password by reading the preceding 3 digits to the password ("ans ...999" which means alphanumeric - special with length max of 999 and 3 digit length info). Lets say the character position of the password would be 107 in this case for arguments sake, so we know to read the 3 numbers before it.
Starting at the character position of the password, mask the number of characters required with XXX. Loop through log until complete.
It does seem as though you're indicating the position of the password and the length of the password will vary. As long as you have the '008' and something like '666' to indicate a starting and stopping point something like this should work.
$filePath = '.\YourFile.log'
(Get-Content $filePath) | ForEach-Object {
$startIndex = $_.IndexOf('008') + 3
$endIndex = $_.IndexOf('666', $startIndex)
$passwordLength = $endIndex - $startIndex
$passwordToReplace = $_.Substring($startIndex,$passwordLength)
$obfuscation = New-Object 'string' -ArgumentList 'X', $passwordLength
$_.Replace($passwordToReplace, $obfuscation)
} | Set-Content $filePath
If the file is too large to load into memory then you will have to StreamReader and StreamWriter to write the content to a new file and delete the old.
Assuming a fixed position where the password-length field starts, based on your sample line (if that position is variable, as you've hinted at, you need to tell us more):
$line = '22222222222222333333333333333333444444444444444444444444455555008PASSWORD6666666666666666677777777777777777777777ccccdddddddddddffffffffffffff'
$posStart = 62 # fixed 0-based pos. where length-of-password field stats
$pwLenFieldLen = 3 # length of length-of-password field
$pwLen = [int] $line.SubString($posStart, $pwLenFieldLen) # extract password length
$pwSubstitute = 'X' * $pwLen # determine the password replacement string
# replace the password with all Xs
$line -replace "(?<=^.{$($posStart + $pwLenFieldLen)}).{$pwLen}(?=.*)", $pwSubstitute
Note: This is not the most efficient way to do it, but it is concise.

How can I convert a number to its English form in Perl?

I need a Perl script which takes numbers as input example 222
and it should output as two hundred twenty two.
Use Lingua::EN::Numbers - turn "407" into "four hundred and seven", etc.
use Lingua::EN::Numbers qw(num2en num2en_ordinal);
my $x = 234;
my $y = 54;
print "You have ", num2en($x), " things to do today!\n";
print "You will stop caring after the ", num2en_ordinal($y), ".\n";
prints:
You have two hundred and thirty-four things to do today!
You will stop caring after the fifty-fourth.
If you read the documentation of the module then you will find that the module also support the following things like,
It can handle integers like "12" or "-3" and real numbers like "53.19".
It also understands exponential notation -- it turns "4E9" into "four times ten to the ninth.
It turns "INF", "-INF", "NaN" into "infinity", "negative infinity", and "not a number", respectively.
Number::Spell can help you:
use Number::Spell;
my $str = spell_number(222);
Here is one:
Number to Word Converter - Perl Engineering Project Download
Description: This basically converts a
number into words. It can only convert
numbers less than or equal of
novemdecillion quantity. It has a
complete input validation process.