Scripting Games: Advanced PowerShell — Event 8

Выполняем работу iTunes 😉 Помнится в нём была подобная функциональность — набить айпод произвольной музыкой из библиотеки под завязку. Впрочем тут условия чуть сложнее 🙂

 

SG8-SongList.ps1

# Загружаем содержимое файла songlist.csv. Import-Csv использовать не получится, # так как он берет заголовки из первой строки, а в этом файле заголовков нет, и # в первой строке находятся данные. $Songs = Get-Content "c:\scripts\songlist.csv" | # Отбираем только строки попадающие под регулярное выражение, заодно # разбирая на группы. where {$_ -match "^(.+),(.+),(.+)$"} | foreach { # Создаем новый, пустой объект. $obj = New-Object "PSObject" # Добавляем к нему свойства со значениями полученными из регулярного # выражения ($Matches). $obj | Add-Member "noteproperty" -Name "Artist" -Value $matches[1] $obj | Add-Member "noteproperty" -Name "Song" -Value $matches[2] # Добавляя свойство Time, преобразовываем значение в тип [TimeSpan] # (отрезок времени). $obj | Add-Member "noteproperty" -Name "Time" -Value ([TimeSpan]("0:"+$matches[3])) # Выводим полученный объект на конвейер. $obj } # В результате в переменной $Songs у нас содержится массив объектов со # свойствами Artist, Song, Time. # Создаем массив $Burnlist, это список песен для записи. $Burnlist = @() # Создаем объект класса Random для генерации произвольных чисел. $r = New-Object random # Запускаем бесконечный цикл. while ($true) { # Получаем произвольную песню из списка. $song = $Songs[$r.next($Songs.length)] # Если в списке $BurnList содержится не более одной песни от $Song.Artist и # в списке еще нет конкретно этой песни... if ((($burnlist | where {$_.artist -eq $song.artist}).count -le 1) ` -and (!($burnlist | where {$_.song -eq $song.song}))) { # Добавляем к списку записи $Song $Burnlist += $song # Считаем какова общая продолжительность песен в $Burnlist: # Создаем переменную $n класса [TimeSpan] [timespan]$n=0 # Добавляем к $n время всех треков из $BurnList $burnlist |%{$n+=$_.time} # Если суммарное время превышает 80 минут, то обнуляем $Burnlist, и он # будет заполняться заново. Не самый оптимальный алгоритм, но... 🙂 if ($n -gt [timespan]::FromMinutes(80)){$Burnlist = @()} # Если суммарное время удовлетворяет условиям задачи (Больше 75 минут и # меньше 80)... if ($n -lt [timespan]::FromMinutes(80) -and $n -gt [timespan]::FromMinutes(75)) { # Cортируем список по исполнителю. $Burnlist | Sort artist | # Выбираем свойства Artist и Song, а свойство Time заменяем # текстовым (вместо [TimeSpan]) с временем в формате который # предпочитают Scripting Guys 🙂 Select Artist, Song, @{n="Time";e={$_.Time -replace "^00:"}} | # Выводим объекты на GridView Out-GridView # Пишем сколько всего времени заняли треки на диске. Write-Host "Total music time: $([int]$n.totalminutes):$($n.seconds)" # Завершаем работу скрипта. Exit } } }

Опять далеко не идеал 😉 Другие варианты: Mow, Per Østergaard, Scripting Guys, Macro Shaw.

PS: Срочно в номер 🙂 Через полтора-два часа (12 MSK) начнется очень интересный вебкаст, рекомендую записаться и посмотреть 😉

Опубликовано в Learn, PowerShell, Scripting, Scripting Games. 1 Comment »

Один ответ to “Scripting Games: Advanced PowerShell — Event 8”

  1. Mc'key Says:

    Мое решение…

    $Grp = @{}
    $Album = @()
    $Complite = $false
    $Total = [TimeSpan] «0:00»
    $RndGen = New-Object Random
    $Songs = Get-Content C:\Scripts\songlist.csv
    $C = $Songs.Count
    while (!$Complite)
    {
    $I = $RndGen.Next($C)
    $S = $Songs[$I]
    $SS = $S.Split(«,»)
    $TT = $Total.Add(«0:»+$SS[2])
    if (($Grp[$SS[0]] -lt 2) -and ($Album -notcontains $I) -and ($TT.TotalMinutes -le 80.0))
    {
    $Album+=$I
    $Grp[$SS[0]]=$Grp[$SS[0]]+1
    $Total = $TT
    $Complite = ($Total.TotalMinutes -ge 75.0) -and ($Total.TotalMinutes -le 80.0)
    }
    }
    » ARTIST SONG TIME»
    «-«*79
    $Album | ForEach-Object {$T=$Songs[$_].Split(«,»);$A=$T[0].PadRight(30);$S=$T[1].PadRight(35);$M=$T[2].PadRight(6);»$A $S $M»} | Sort
    «»
    «Total music time: «+[int]$Total.TotalMinutes+»:»+$Total.Seconds.ToString().PadLeft(2,»0″)

    Врядли тоже самое оптимальное.


Обсуждение закрыто.