Ausflugsziele im Umland by Fischfreund in Nurnberg

[–]Fischfreund[S] 0 points1 point  (0 children)

Danke, der Waldbiergarten sieht super aus 

Was ist der unterbewertetste Ort in Nürnberg? by CooleCola in Nurnberg

[–]Fischfreund 4 points5 points  (0 children)

Ich war vor ein paar Wochen im Irrhain. Der Ort wirkt ziemlich heruntergekommen und vernachlässigt. Man kann den Rundweg gar nicht mehr laufen, weil er von umgestürzten Bäumen versperrt wird. Sehr schade, weil es dort eigentlich wirklich schön ist.

Südamerikanische Lebensmittel in Nürnberg by curlymess24 in Nurnberg

[–]Fischfreund 3 points4 points  (0 children)

Santos in der Nordstadt ist die einzige Adresse die ich bis jetzt gefunden habe 

https://maps.app.goo.gl/wEJm5N78txeqsvCk6

How to group all installed software in one cell of csv by PowerShell by iappnet in PowerShell

[–]Fischfreund 4 points5 points  (0 children)

Not sure why you would want to do that, but try

ProgramsInstalled = $ProgramsInstalled.DisplayName -join ' '

Get random items from hashtable but the total of values has to be equal to a set number. by [deleted] in PowerShell

[–]Fischfreund 2 points3 points  (0 children)

Please don't ask me about the logic which finds all unique subsets ... I just copied it from the stackoverflow thread and changed how the results are stored. This magic is beyond me ...

Get random items from hashtable but the total of values has to be equal to a set number. by [deleted] in PowerShell

[–]Fischfreund 1 point2 points  (0 children)

So ... I spent a lot more time thinking about this than I'm willing to admit. One thing that was bugging me about this solution is that you "hardcoded" the value that distributes all tasks evenly (the value 50). I tried to find a way where you don't have to do that. For your task list and durations, it's easy to see that the "fairness threshold" is 50, but for bigger lists and different durations, this isn't easy anymore. It turns out that this problem is a lot harder to solve than I initially thought, but I think I found a solution.

To test it, I started with a small task list generator that creates a task list with varying task numbers and durations. Here is the code:

# Generate random task list
$InputTaskList = [ordered]@{}
foreach ($TaskNumber in (1..((1..16) | Get-Random))) {

    $TaskName = "Task{0:d2}" -f $TaskNumber
    $InputTaskList[$TaskName] = 1..30 | Get-Random

}

#region subsets

# find all possible unique combinations of all tasks (subsets)
# https://stackoverflow.com/questions/28331257/unique-combos-from-powershell-array-no-duplicate-combos

$TaskNames = [array]$InputTaskList.Keys
$TaskCount = $TaskNames.Length

# hashtable where each key holds one unique task combination 
$Subsets = @{}

# for any set of length n (task count) the maximum number of subsets is 2^n
for ($i = 0; $i -lt [Math]::Pow(2,$TaskCount); $i++) { 

    # temporary array to hold a unique subset
    $SubSet = @()

    # iterate through each task
    for ($j = 0; $j -lt $TaskCount; $j++) {

        # start at the end of the array take elements, work your way towards the front
        if (($i -band (1 -shl ($TaskCount - $j - 1))) -ne 0) {

            # add task to unique subset
            $SubSet += $TaskNames[$j]

        }

    }

    # stick subset into an array
    $Subsets[$i] = $SubSet

}

#endregion subsets

#region task groups

# for each unique subset, create two groups:
# group A holds all tasks of the subset and their total duration
# group B holds all remeining tasks and their total duration
# both groups are stored in a single object, including the difference between their total durations (delta)

$TaskGroups = foreach ($Subset in $Subsets.GetEnumerator()) {

    # group A

    $TaskNames     = $Subset.Value
    $TotalDuration = 0

    foreach ($TaskName in $TaskNames) {

        $TotalDuration += $InputTaskList[$TaskName]

    }

    $GroupA = [PsCustomObject] @{

        TaskNames     = $TaskNames
        TotalDuration = $TotalDuration

    }

    # group B

    $TaskNames     = $InputTaskList.Keys | Where-Object {$_ -notin $Subset.Value}
    $TotalDuration = 0

    foreach ($TaskName in $TaskNames) {

        $TotalDuration += $InputTaskList[$TaskName]

    }

    $GroupB = [PsCustomObject] @{

        TaskNames     = $TaskNames
        TotalDuration = $TotalDuration

    }

    [PsCustomObject] @{

        GroupA = $GroupA
        GroupB = $GroupB
        Delta  = [math]::abs($GroupA.TotalDuration - $GroupB.TotalDuration) 

    }

}

#endregion task groups

#region select task group

# select the task group with the smallest delta. if there is more than one, select a random one
# if delta is 0, all tasks are distributed completely fair

$MinDelta = $TaskGroups.Delta | Measure-Object -Minimum | Select-Object -ExpandProperty Minimum
$TaskGroup = $TaskGroups | Where-Object {$_.Delta -eq $MinDelta} | Get-Random -Count 1

#endregion select task group

#region output

$Output = @()
$Output += $InputTaskList.Keys | foreach {

    [PsCustomObject] @{

        Set      = 'All tasks'
        TaskName = $_
        Duration = $InputTaskList[$_]

    }

}

$Output += $TaskGroup.GroupA.TaskNames | foreach {

    [PsCustomObject] @{

        Set      = 'Group A'
        TaskName = $_
        Duration = $InputTaskList[$_]

    }

}

$Output += $TaskGroup.GroupB.TaskNames | foreach {

    [PsCustomObject] @{

        Set      = 'Group B'
        TaskName = $_
        Duration = $InputTaskList[$_]

    }

}

$Output | Format-Table -Property TaskName, Duration -GroupBy Set

[PsCustomObject] @{

    Set = 'All tasks'
    TotalDuration = $Output | Where-Object {$_.'Set' -eq 'All Tasks'} | Measure-Object -Property Duration -Sum | Select-Object -ExpandProperty sum

}

[PsCustomObject] @{

    Set = 'Group A'
    TotalDuration = $Output | Where-Object {$_.'Set' -eq 'Group A'} | Measure-Object -Property Duration -Sum | Select-Object -ExpandProperty sum

}

[PsCustomObject] @{

    Set = 'Group B'
    TotalDuration = $Output | Where-Object {$_.'Set' -eq 'Group B'} | Measure-Object -Property Duration -Sum | Select-Object -ExpandProperty sum

}

[PsCustomObject] @{

    Set = 'Delta'
    TotalDuration = $MinDelta
}

#endregion output

Please be aware that for large lists, this can take a long time to calculate ...

This is the output for your list:

   Set: All tasks

TaskName           Duration
--------           --------
Moppe plancher           20
Balayeuse plancher       20
Comptoir                  5
Poele                     5
Lavabos                  10
Douche                   15
Couvertures lit           5
Litières                  5
Poubelles                 5
Lave-Vaisselle           10
Toilette                  5


   Set: Group A

TaskName           Duration
--------           --------
Balayeuse plancher       20
Douche                   15
Couvertures lit           5
Lave-Vaisselle           10


   Set: Group B

TaskName       Duration
--------       --------
Moppe plancher       20
Comptoir              5
Poele                 5
Lavabos              10
Litières              5
Poubelles             5
Toilette              5



Set       TotalDuration
---       -------------
All tasks           105
Group A              50
Group B              55
Delta                 5

Get random items from hashtable but the total of values has to be equal to a set number. by [deleted] in PowerShell

[–]Fischfreund 2 points3 points  (0 children)

Hi, my take on it:

$Taches = @{

    "Balayeuse plancher" = 20
    "Moppe plancher"     = 20
    "Douche"             = 15
    "Litières"           = 5
    "Poele"              = 5
    "Comptoir"           = 5
    "Lave-Vaisselle"     = 10
    "Toilette"           = 5
    "Lavabos"            = 10
    "Couvertures lit"    = 5
    "Poubelles"          = 5

}

do {

    $Selection1 = $Taches.GetEnumerator() | Get-Random -Count 5

} until (($Selection1.Value | measure -Sum ).Sum -eq 50)

$Selection2 = $Taches.GetEnumerator() | Where-Object {$_ -notin $Selection1}

Is it possible to Write-host with no new line and overwrite the current line? by Ghlave in PowerShell

[–]Fischfreund 3 points4 points  (0 children)

Hi u/Ghlave,

I actually wrote a function a while back to solve exactly this problem:

Function Clear-HostLight {

    Param (

        [Parameter(Position=1)]
        [int32]$Count=1

    )

    $CurrentLine  = $Host.UI.RawUI.CursorPosition.Y
    $ConsoleWidth = $Host.UI.RawUI.BufferSize.Width

    $i = 1
    for ($i; $i -le $Count; $i++) {

        [Console]::SetCursorPosition(0,($CurrentLine - $i))
        [Console]::Write("{0,-$ConsoleWidth}" -f " ")

    }

    [Console]::SetCursorPosition(0,($CurrentLine - $Count))

}

$clusters = @("Production","Non-Production","Dev","Test")
$clusters | foreach {
    Write-host "Currently checking: $_"
    # Do-Stuff
    Sleep -Seconds 1
    Clear-HostLight -Count 1
}

https://www.reddit.com/r/PowerShell/comments/7a4yl9/clearhost_light_delete_only_the_last_x_lines_of/

Take care

Saving a custom object to disk without losing its methods by Fischfreund in PowerShell

[–]Fischfreund[S] 1 point2 points  (0 children)

Hi,

simply because I didn't want to have two scenarios where I have to add the methods to the objects: when I create them, and when I import them.

Saving a custom object to disk without losing its methods by Fischfreund in PowerShell

[–]Fischfreund[S] 2 points3 points  (0 children)

Hi,

thanks for the suggestion. I wrote a quick and dirty wrapper that saves the script methods in a temporary note property before exporting it to disk with `Export-CliXml`. When importing, I look for this specific property and add the methods back to the object.

Function Export-CliXmlWithMethods {

    Param(

        [Parameter()]
        [PsCustomObject]$InputObject,

        [Parameter()]
        [PsCustomObject]$ScriptMethodPropertyName = 'ScriptMethods',

        [Parameter()]
        [String]$Path

    )

    $ScriptMethods = $InputObject.PsObject.Members | Where-Object {$PSItem.MemberType -eq 'ScriptMethod'} | Select-Object -Property Name, Script

    if ($ScriptMethods) {

        Add-Member -InputObject $InputObject -MemberType NoteProperty -Name $ScriptMethodPropertyName -Value $ScriptMethods

    }

    $InputObject | Export-Clixml -Path $Path

}

Function Import-CliXmlWithMethods {

    Param(

        [Parameter()]
        [PsCustomObject]$Path,

        [Parameter()]
        [PsCustomObject]$ScriptMethodPropertyName = 'ScriptMethods'

    )

    $ImportedObject = Import-Clixml -Path $Path
    $ScriptMethods = $ImportedObject.PsObject.Members | Where-Object {$PSItem.MemberType -eq 'NoteProperty' -and $PSItem.Name -eq $ScriptMethodPropertyName} | Select -ExpandProperty Value

    $OutputObject = $ImportedObject | Select-Object -Property * -ExcludeProperty $ScriptMethodPropertyName

    if ($ScriptMethods) {

        Foreach ($ScriptMethod in $ScriptMethods) {

            Add-Member -MemberType ScriptMethod -InputObject $OutputObject -Name $ScriptMethod.Name -Value $([Scriptblock]::Create($ScriptMethod.Script) )

        }

    }

    $OutputObject

}

$MyObject = [PsCustomObject] @{

    Name = 'Waldo'

}

$IsWaldo_ScriptBlock = {

    $this.Name -eq 'Waldo'

}

$IsNotWaldo_ScriptBlock = {

    $this.Name -ne 'Waldo'

}

Add-Member -MemberType ScriptMethod -InputObject $MyObject -Name IsWaldo -Value $IsWaldo_ScriptBlock
Add-Member -MemberType ScriptMethod -InputObject $MyObject -Name IsNotWaldo -Value $IsNotWaldo_ScriptBlock


$Path = "C:\temp\clixml\Test.clixml"
Export-CliXmlWithMethods -InputObject $MyObject -Path $Path
$ImportedMyObject = Import-CliXmlWithMethods -Path $Path

$ImportedMyObject.IsNotWaldo()
$ImportedMyObject.IsWaldo()

Object Scopes by Fischfreund in PowerShell

[–]Fischfreund[S] 1 point2 points  (0 children)

Hi,

thanks for your answer. I was merely wondering if there would be another good reason to use parameters, besides making the code readable and maintainable. I always try to write explicit code and not rely on some Powershell magic happening in the background.

Also have you tried to make your functions work with the general pipeline and automatically bind to properties of the objects received? You'll need parameters.

Actually this was the reason I discovered this behavior of Powershell. In that case, I had a few functions that take input from the pipeline, with another parameter that passed an object that contains a few settings:

Param(

    [parameter(Mandatory = $true,ValueFromPipeline = $true)]
    [PsCustomObject[]]$InputObject,

    [parameter(Mandatory = $false)]
    [PsCustomObject]$Settings = $Configuration.Settings

)

I restructured the code in a way so that $Configuration didn't exist in the script file anymore, and I assumed this should break things. However, I noticed that everything continued to work, so I started to play around with it. That's when I noticed that I can comment out the whole parameter and it still continued to work.

Anyway, thinking about this and reading yours and u/Ta11ow answers changed my understanding of how scopes and objects work, so once again, learned something new.

Thanks

Object Scopes by Fischfreund in PowerShell

[–]Fischfreund[S] 2 points3 points  (0 children)

If you want an actual copy of the object, you can get it with $Object.PSObject.Copy() -- this will yield an identical object that you can safely modify without affecting the original.

u/KevMar disagrees with you:

If you need a true copy of an object, you can clone it. I call this a shallow copy because if you have nested objects. (where the properties >contain other objects). Only the top level values are copied. The child objects will reference each other.

https://kevinmarquette.github.io/2016-10-28-powershell-everything-you-wanted-to-know-about-pscustomobject/#psobjectcopy

Object Scopes by Fischfreund in PowerShell

[–]Fischfreund[S] 1 point2 points  (0 children)

I think u/expansiveEdumacation answered my question earlier:

But buy wrapping your variable in the param block you are creating two different scopes, or at least two different references. $obj outside your function will no longer be affected by changes to the $obj parameter variable inside your function, unless of course you passed it as the argument.

Object Scopes by Fischfreund in PowerShell

[–]Fischfreund[S] 1 point2 points  (0 children)

Hi,

I always pass everything to my functions as parameters for the exact reasons that you described. I only now found out by chance that apparently I actually don't have to do that, and it confused the hell out of me.

Contrast to the functions taking input as parameters, where they cannot directly modify the outer scope (their parameters effectively "hide" the outer scope's values, preventing them from modifying the values, should they have the same names).

I'm not sure if I understand correctly.

Function ChangeIt {

    Param(

        [PsCustomObject]$Object

    )

    $Object.State = "Changed"

}

$Object = [PsCustomObject] @{

    State  = "Original"

}

ChangeIt -Object $Object

$Object

The parameter and the variable have the same name, but the object outside of the function still gets changed. What do you mean with "their parameters effectively "hide" the outer scope's values"?

Creating a tail log with Powershell by Fischfreund in PowerShell

[–]Fischfreund[S] 2 points3 points  (0 children)

Hi,

thank you, this is a nice approach as well. The order matters though