Extreme Problems with PowerShell Bob Exercise

Hi, I just started Exercism a few days ago, and I saw that one of the tracks was PowerShell, and I was interested, so I did the Hello World and started the track. I tried the “Bob” exercise (the one where you write cases for what Bob would say if provided with input), and I think it’s now 3 hours since I started trying to figure this out. I even went back and unlocked the tab for Community Solutions, but I don’t want to just copy and paste to get the solution, y’know?

So, I was wondering if perhaps (cause I’ve never learned this language, although I have experience with Python, JavaScript, HTML, CSS, and various miscellaneous knowledge with other languages) is the main reason that I’m failing that I don’t know the language? I looked up basic syntax, and case-specific syntax and stuff, but nothing I try seems to be working. I even tried asking ChatGPT (on my Dad’s Plus, cause I can’t donate cause I’m not 18+ so I can’t support myself, and my fam is kinda tight on money atm), but that didn’t seem to help either. Should I just go find a course on PowerShell and come back after?

Sorry if this is a dumb/naive question.

Bob is one of the trickier exercises in some regards. Are you having trouble with language syntax or with being able to solve all the corner cases? If you’re comfortable with other languages, consider trying to solve Bob in one of those other languages, first. Then you can solve Bob in PowerShell once you have a working algorithm; that will help isolate language-specific challenges vs general exercise related challenges.

1 Like

It’s not really the language syntax at this point, but more the fact that I can’t seem to get every edge-case covered, and then if I solve a new one, one of the old ones seem to re-appear. That’s a great idea, though, thank you. I’ll do that and see if I can then translate that into PowerShell.

Okay, so I successfully solved the Python exercise in my own IDE because I haven’t unlocked the Exercism one yet (and realized I was probably running into some logic issues earlier), but after translating that into PowerShell, now I’m running into a lot of null variable issues. Apparently, Python handles calling methods on null variables really well, and PowerShell does not. So I wrapped my essential logic variables in a if block to check if they were null, but now all my logic is funky. I don’t even know what to do now.

I don’t know PowerShell but you can try pasting your code here and/or on the Discord and someone who does know PowerShell may be able to help with syntax and PowerShell issues.

1 Like

Well, thank you so much for helping me, I think you restored some of my sanity with that idea, lol. I’ll just post my PowerShell code and Python code in a direct reply to the topic. Have a good night/day! :smiley:

So after going back and solving it in Python, this is what I came up with. First, this is the python code:

import re

def getBobResponse(string):
upper_string = string.upper()
lower_string = string.lower()
stripped = string.strip()
is_question = stripped.endswith("?")
is_numbers = lower_string == upper_string
if string == upper_string and is_question == True and is_numbers == False:
    return "Calm Down, I know what I'm doing!"
elif string == upper_string and is_numbers == False:
    return "Whoa, chill out!"
elif is_question == True:
    return "Sure."
elif string.isspace() == True or string == "" or re.match(r'^[\t\n\r]*$', string):
    return "Fine. Be that way!"
else:
    return "Whatever."

And here is the PowerShell:

if ($string -ne $null) {
    $upper_string = $string.ToUpper()
    $lower_string = $string.ToLower()
    $stripped = $string.Trim()
    $isQuestion = $stripped.EndsWith("?")
    $isNumbers = ($lowerString -eq $upperString)
}
if ($string -eq $upperString -and $isQuestion -and -not $isNumbers) {
    return "Calm Down, I know what I'm doing!"
}
elseif ($string -eq $upperString -and -not $isNumbers) {
    return "Whoa!, chill out!"
}
elseif ($isQuestion) {
    return "Sure."
}
elseif ([string]::IsNullOrWhiteSpace($string) -or $string -eq "" -or ($string -match '^[`t`n`r]*$')) {
    return "Fine. Be that way!"
}
else {
    return "Whatever."
}
}

Some error messages (I put the logic variables into an if block because it was raising null variable errors, and now the logic that was working in Python is not working.):

Message: Expected strings to be the same, but they were different.
Expected length: 9
Actual length:   17
Strings differ at index 2.
Expected: 'Whatever.'
But was:  'Whoa!, chill out!'
           --^

Stack-trace: at Get-BobResponse -HeyBob "Tom-ay-to, tom-aaaah-to." | Should -BeExactly "Whatever.",

Note: It looks like everything is just going by default to Whoa, chill out. Is there some PowerShell logic that I’m missing?

That code is … challenge to read. You can use a code block by surrounding code inside ```

You may also want to include (in code blocks) any errors and/or failed test outputs you are getting

1 Like

That is much better, thank you. I haven’t used these kinds of forums much yet.

So… the input "Tom-ay-to, tom-aaaah-to." is returning the Whoa response incorrectly. What triggers that return value? What tests are returning the wrong result?

Well, it’s supposed to be that as long as the string is exactly equivalent to the upperString, then it’s in capital letters. The isNumbers is supposed to check that the string isn’t numbers, cause if it was then the upper and lower case versions of the string would be exactly the same. So as long as it is in uppercase and it isn’t numbers it returns ‘Whoa, chill out.’ At least that’s how it should work? Um, basically every test that isn’t supposed to be Whoa, chill out is failing.

Hey there, I’m one of the contributors for the powershell track. I didn’t author this one but i’ve solved it.
From a quick glance of your code posted above, one of the major issue is you declared:

$lower_string
$upper_string

#but then you use
$lowerString
$upperString

Fix it and see if everything go well this time.

Edit: naming convention is important to avoid small mistake like this. There is no enforce rule for powershell but in generally people often use camelcase for vars. You can stick with snakecase just fine but remember to keep them consistent.

Thank you for finding that! It didn’t end up solving it, but that was very useful, and I can’t believe I didn’t realize I did that.

Okay, I went over everything, fixed a bunch of variable issues and added a couple logic issues. I’m now solving a majority of the tests, but it seems like there’s an issue with the uppercase matching. Is there a more efficient way to do that that I’m unaware of?

Here’s the current version:

if ($HeyBob -ne $null) {
        $upperString = $HeyBob.ToUpper()
        $lowerString = $HeyBob.ToLower()
        $stripped = $HeyBob.Trim()
        $isQuestion = $stripped.EndsWith("?")
        $isNumbers = $HeyBob -match '^\d+$' -or $lowerString -eq $upperString
    }

    if (($HeyBob -ceq $upperString) -and ($isQuestion) -and -not ($isNumbers)) {
        return "Calm down, I know what I'm doing!"
    }
    elseif (($HeyBob -ceq $upperString) -and -not ($isNumbers)) {
        return "Whoa, chill out!"
    }
    elseif ($isQuestion) {
        return "Sure."
    }
    elseif ([string]::IsNullOrWhiteSpace($HeyBob) -or $HeyBob -eq "" -or ($HeyBob -eq '^[`t`n`r]*$')) {
        return "Fine. Be that way!"
    }
    else {
        return "Whatever."
    }

I appreciate all the help. I’ve been trying different comparison operators for a while, but that doesn’t seem to help. Here’s an example error:

Message: Expected strings to be the same, but they were different.
Expected length: 33
Actual length:   5
Strings differ at index 0.
Expected: 'Calm down, I know what I'm doing!'
But was:  'Sure.'
           ^

Stack-trace: at Get-BobResponse -HeyBob "WHAT THE HELL WERE YOU THINKING?" | Should -BeExactly "Calm down, I know what I'm doing!"

Message: Expected strings to be the same, but they were different.
Expected length: 16
Actual length:   9
Strings differ at index 2.
Expected: 'Whoa, chill out!'
But was:  'Whatever.'
           --^

Stack-trace: at Get-BobResponse -HeyBob "1, 2, 3 GO!" | Should -BeExactly "Whoa, chill out!"

Nevermind! I figured it out! Turns out I wasn’t catching all the cases because I was over-complicating the beginning process with the logic variables. I made them actually logic variables and it worked! Thank you @IsaacG and @glaxxie so much for your help! It meant a lot! :heart:

1 Like

Congrats. Yes, turning them into actual logical variable and then from that point forward it is just a matter of logical if-else and operators combination to get to the return that you want.

My approach to this was usually first trim the string, and then operate on that new string to get the rest of the conditional vars:
Am i yelling, am i asking a question, and am i being silent.
For example, you can simplify the silence check after trimming the string:

$isSilence = $trimmedStr.Length -eq 0 
# this is easy to see, if you trim all the space, len is 0
or
$isSilence = -not $trimmedStr  
# this is a bit more confusing and language dependent, i offer this because you came from python where they also consider "" as false, so we negate it and got what we want
1 Like

Okay, yes that makes a lot of sense. I think I was mostly very dismissive this whole time of actually just trimming the string and then going from there. I think I thought about it as even if there’s whitespaces (etc.) this should still work, and that seems like it definitely isn’t the way to go. Checking for/working with additional characters isn’t something I’m used to, and I think Python is a bit more forgiving with that, so this was a good lesson for me.