Блок If/ElseIf не работает с -or

У меня проблема со сценарием, который я пишу для своего сына. Мое намерение — просто напомнить ему, чтобы он помнил о своих делах. Я только недавно начал использовать PowerShell, и мне это очень нравится. Я купил пару книг и просмотрел множество других постов.

То, что у меня есть до сих пор, ниже, кажется, если оценки не работают правильно с -or (или, может быть, я ошибся?)

    ## REMINDERS TO DO CHORES ##

$sun = "Sunday"
$mon = "Monday"
$tue = "Tuesday"
$wed = "Wednesday"
$thu = "Thursday"
$fri = "Friday"
$sat = "Saturday"

$today = (get-date).DayOfWeek

$choreVac = "Vacuum the rooms and stairs"
$choreBath = "Clean the Bathroom Including emptying the garbage"
$choreOther = "No Chores Today -- But keep dishes done up"


if($today -eq $mon -or $wed -or $fri) {
msg /time:2500 * "Today is a Chore Day:  your job is to $choreVac" 
}

elseif ($today -eq $tue -or $sat ) {
msg /time:2500 * "Today is a Chore Day: your job is to $choreBath and PLEASE do a good job"
}
else {
msg /time:2500 * $choreOther
}

Проблема в том, что я не думаю, что он правильно оценивается в этот день, поэтому на сегодня, вторник, результат оценки равен $mon -or $wed -or $fri.

Если я перекодирую это каждый день следующим образом, он будет работать, как и ожидалось. Почему не работает с -or?

if($today -eq $tue) {
msg /time:2500 * $choreBath
}

person PCPaul    schedule 19.08.2015    source источник
comment
Ааа я только что понял. Я должен полностью квалифицировать его, если ($today -eq $mon -or $today -eq $wed -or $today -eq $fri) { это работает   -  person PCPaul    schedule 19.08.2015
comment
Не стесняйтесь опубликовать ответ на свой вопрос с подробным описанием решения, которое вы нашли.   -  person Guvante    schedule 19.08.2015
comment
Вы не должны давать ответ на вопрос выше :) Я удалил эту часть.   -  person dan-gph    schedule 19.08.2015
comment
@ dan-gph Спасибо, Дэн, я пока не вижу возможности голосовать за ваши комментарии, но не беспокойтесь. Я ценю это.   -  person PCPaul    schedule 19.08.2015


Ответы (3)


Как вы сами обнаружили, PowerShell не оценивал ваш оператор if как вы предполагали. Ваше выражение можно было бы лучше понять так:

if(($today -eq $mon) -or ($wed) -or ($fri))

Как и в вашем комментарии, код, который вы хотели, был

$today -eq $mon -or $today -eq $wed -or $today -eq $fri

или другой способ посмотреть на это.

($today -eq $mon) -or ($today -eq $wed) -or ($today -eq $fri)

PowerShell не нуждается в скобках, но их полезно использовать, если что-то идет не так.

Когда строки не нулевой/нулевой длины в PowerShell имеют значение true при преобразовании в логические значения. Сосредоточившись на втором предложении, его можно было бы переписать как

"Wednesday" -or "Friday"

То есть всегда true. Вот почему ваш оператор if срабатывал, когда вы этого не ожидали.

То, что вы закодировали, имело некоторый логический смысл, но было синтаксически неверным. Если вы еще не знакомы с другим подходом, с которым я хотел бы вас познакомить, это switch. Это помогло бы уменьшить беспорядок во всех операторах if и было бы особенно полезно, если бы они усложнялись по мере того, как рутинная работа развивалась с течением времени.

$today = (get-date).DayOfWeek

$choreVac = "Vacuum The Apt"
$choreBath = "Clean the Bathroom Including empting the garbage"
$choreOther = "NO CHORES TODAY -- BUT YOU CAN Keep dishes done up, and Keep Garbage from Overflowing AND CLEAN YOUR ROOM and OR Do Laundry!!!. Especially your bedding"

Switch ($today){
    {$_ -in 1,3,5}{$message = "Today is a Chore Day:  Your job is to`r$choreVac"}
    {$_ -in 2,6}{$message = "Today is a Chore Day:  Your job is to`r$choreBath and PLEASE do a good job"}
    default{$message = $choreOther}
}

msg /time:2500 * $message

Мы убрали все вызовы msg в один оператор, поскольку изменяется только $message. Если рабочий день не охвачен пунктом в переключателе, по умолчанию используется просто $choreOther.

Также дни недели могут быть представлены целыми числами, как показано выше. Возможно, это может снизить читабельность кода, но я думаю, что это перебор.

person Matt    schedule 19.08.2015
comment
@Matt Спасибо, переключатель отличный. Это больше похоже на оператор case, который я использовал в PL/SQL или который я видел в других языках, таких как C/C++, что тоже было забавно. +1 - person PCPaul; 19.08.2015

Вот полный код, исправленный и работающий так, как я хотел.

    ## REMINDERS TO DO CHORES ##

$sun = "Sunday"
$mon = "Monday"
$tue = "Tuesday"
$wed = "Wednesday"
$thu = "Thursday"
$fri = "Friday"
$sat = "Saturday"

$today = (get-date).DayOfWeek

$choreVac = "Vacuum The Apt"
$choreBath = "Clean the Bathroom Including empting the garbage"
$choreOther = "NO CHORES TODAY -- BUT YOU CAN Keep dishes done up, and Keep Garbage from Overflowing AND CLEAN YOUR ROOM and OR Do Laundry!!!. Especially your bedding"

if($today -in ($mon, $wed ,$fri) ) {
msg /time:2500 * "Today is a Chore Day:  your job is to $choreVac" 
}

elseif ($today -in ($tue,$sat)) {
msg /time:2500 * "Today is a Chore Day: your job is to $choreBath and PLEASE do a good job"
}
else {
msg /time:2500 * $choreOther
}
person PCPaul    schedule 19.08.2015
comment
Вы можете написать это более компактно с помощью оператора -in: if ($today -in ($mon, $wed, $fri)) { } - person dan-gph; 19.08.2015
comment
@dan-gph +10 Мне так даже больше нравится! намного чище. Ваше здоровье. - person PCPaul; 19.08.2015

Вы также можете использовать Hashtables для обработки списков домашних дел и связанных с ними дней. Следующее позволит вам легко добавлять работу по дому в любой день (или даже поместить несколько дел в один день).

$chores = @{Vac   = "Vacuum the Appt";
            Bath  = 'Clean the bathroom including emptying the garbage';
            Other = 'Nothing today -- But keep dishes done up'
           }

$day = @{Sunday    = $chores.Other;
         Monday    = $chores.Vac;
         Tuesday   = $chores.Bath;
         Wednesday = @($chores.Vac,$chores.Other);
         Thursday  = $chores.Other;
         Friday    = $chores.Vac;
         Saturday  = $chores.Bath;
        }

$base = "Chores for today: "
$today = (Get-Date).DayOfWeek
if ($day."$today".count -gt 1) {
    $first = "`n    " + $day."$today"[0]
    $rest = for ($i = 1; $i -lt $day."$today".count; $i++) {
        "`n    " + $day."$today"[$i]
    }

    $msg = $base + $first + $rest
} else {
    $msg = $base + "`n    " + $day."$today"
}

msg /time:2500 * $msg

Если вы не хотите поддерживать наличие нескольких дел в день (что выше относится к среде), просто замените весь блок If/Else предложением else, и он просто перечислит обязанности дня.

person Jonathan Leech-Pepin    schedule 09.09.2015