问:
Output is incorrect can you nest if statement into loops for array calculation?
Here is the full source code It is not outputting the correct persons that make the most and the least. My best guess is the if statement inside the loop for calculations on pay if the person makes works over 40 hours. Code is simple learning C#. What is the best way to fix this.... sorry I know this is a probably a simple issue i'm missing. COMMENTS TO LABEL

```<code>{
class Program
{
    const double FEDERAL_TAX_DEDUCTION = .10; //Federal Tax 10% of Gross Income
    const double STATE_TAX_DEDUCTION = .05;   //State Tax 5% of Gross Income
    const int    HOURS_OVERTIME = 40;         //# of Hours Needed For Overtime Pay Rate
    const double OVERTIME_PAY_DIFF = 1.5;     //150% of Normal Pay

    static void Main(string[] args)
    {
        int MAX_LIST_VALUE;  //How Many Workers There Are For Array Limit.

        Write("How Many Workers Are Currently Working? ");                  //Asks For User Input # Of Workers
        MAX_LIST_VALUE = Convert.ToInt32(ReadLine());

        string[] workerName = new string[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.Blue;
            WriteLine("Please Enter The Worker's Name: ");        //Asks For User Input For Worker's Names
            workerName[i] = ReadLine();
        }
        double[] workerWages = new double[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.DarkYellow;
            WriteLine("Please Enter " + workerName[i] + "'s Hourly Wage: "); //Asks For User Input For Worker's Wage
            workerWages[i] = Convert.ToDouble(ReadLine());
        }
        double[] workerWeeklyHours = new double[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.DarkCyan;
            Write("How Many Hours Has {0} Worked This Week? ", workerName[i]); //Asks For User Input For Hours Worked
            workerWeeklyHours[i] = Convert.ToDouble(ReadLine());
        }
        double[] workersRegularPay = new double[MAX_LIST_VALUE];
        double[] workerGrossIncome = new double[MAX_LIST_VALUE];
        double[] workerStateTaxAmount = new double[MAX_LIST_VALUE];                //All Calculation Arrays
        double[] workerFederalTaxAmount = new double[MAX_LIST_VALUE];
        double[] workerNetIncome = new double[MAX_LIST_VALUE];
        double[] workerOvertimeHours = new double[MAX_LIST_VALUE];
        double[] workerOvertimePay = new double[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            if (workerWeeklyHours[i] > HOURS_OVERTIME)                                                    //If Hours # is > 40.
            {
                workerOvertimeHours[i] = workerWeeklyHours[i] - HOURS_OVERTIME;
                workerOvertimePay[i] = workerOvertimeHours[i] * (workerWages[i] * OVERTIME_PAY_DIFF);
                workerGrossIncome[i] = workerOvertimePay[i] + workersRegularPay[i];
            }
            else
            {
                workersRegularPay[i] = workerWeeklyHours[i] * workerWages[i];
                workerGrossIncome[i] = workerWeeklyHours[i] * workerWages[i];
                workerStateTaxAmount[i] = workerGrossIncome[i] * STATE_TAX_DEDUCTION;
                workerFederalTaxAmount[i] = workerGrossIncome[i] * FEDERAL_TAX_DEDUCTION;
                workerNetIncome[i] = workerGrossIncome[i] - workerFederalTaxAmount[i] - workerStateTaxAmount[i];
                workerOvertimePay[i] = 0;
                workerOvertimeHours[i] = 0;
            }
        }
        ForegroundColor = ConsoleColor.Blue;
        WriteLine("\nNAMES ARE BLUE.");
        ForegroundColor = ConsoleColor.DarkYellow;
        WriteLine("HOURLY WAGES ARE DARK YELLOW.");
        ForegroundColor = ConsoleColor.DarkCyan;
        WriteLine("HOURS WORKED ARE DARK CYAN.");
        ForegroundColor = ConsoleColor.Green;
        WriteLine("NET INCOMES ARE GREEN.");
        ForegroundColor = ConsoleColor.Red;
        WriteLine("-----------------------------");
        WriteLine("There Are " + MAX_LIST_VALUE + " Workers!");  //Echo Of All Data Entered & Calculated For Workers
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.Blue;
            WriteLine("\nWorker's Name: " + workerName[i]);
            WriteLine("-----------------------------");
            ForegroundColor = ConsoleColor.DarkYellow;
            WriteLine(workerName[i] + "'s Hourly Wage: " + workerWages[i].ToString("C"));
            ForegroundColor = ConsoleColor.DarkCyan;
            WriteLine(workerName[i] + "'s Hours Worked This Week: " + workerWeeklyHours[i]);
            ForegroundColor = ConsoleColor.White;
            WriteLine(workerName[i] + "'s Regular Pay: " + workersRegularPay[i].ToString("C"));
            WriteLine(workerName[i] + "'s Gross Income Pay: " + workerGrossIncome[i].ToString("C"));
            WriteLine(workerName[i] + "'s State Tax Amount: " + workerStateTaxAmount[i].ToString("C"));
            WriteLine(workerName[i] + "'s Federal Tax Amount: " + workerFederalTaxAmount[i].ToString("C"));
            ForegroundColor = ConsoleColor.Green;
            WriteLine(workerName[i] + "'s Net Income: " + workerNetIncome[i].ToString("C"));
            WriteLine(workerName[i] + "'s Overtime Hours: " + workerOvertimeHours[i]);
            WriteLine(workerName[i] + "'s Overtime Pay (if any): " + workerOvertimePay[i].ToString("C"));
        }
        ForegroundColor = ConsoleColor.Red;
        WriteLine("\nPress Enter To Continue For The Worker's That Earned The Least & The Most.");
        ReadLine();

        int minIndex = 0;
        string workerLeast = "null";
        double workerRegularPayLeast = 0,
               workerGrossIncomeLeast = 0,
               workerOverTimeLeast = 0;
        int maxIndex = 0;
        string workerMost = "null";
        double workerRegularPayMost = 0,
               workerGrossIncomeMost = 0,
               workerOverTimeMost = 0;

        for (int i = 0; i < workerGrossIncome.Length; i++)         //Calculation For Worker That Made The LEAST
            if (workerGrossIncome[i] < workerGrossIncome[minIndex])
            {
                minIndex = i;
                workerLeast = workerName[i];
                workerRegularPayLeast = workersRegularPay[i];
                workerGrossIncomeLeast = workerGrossIncome[i];
                workerOverTimeLeast = workerOvertimePay[i];
            }
        for (int i = 0; i < workerGrossIncome.Length; i++)         //Calculation For Worker That Made The MOST
            if (workerGrossIncome[i] >= workerGrossIncome[maxIndex])
            {
                maxIndex = i;
                workerMost = workerName[i];
                workerRegularPayMost = workersRegularPay[i];
                workerGrossIncomeMost = workerGrossIncome[i];
                workerOverTimeLeast = workerOvertimePay[i];
            }
        ForegroundColor = ConsoleColor.Green;
        WriteLine("\nThe Worker That Earned The Least Is {0}.", workerLeast);
        WriteLine("-----------------------------");
        ForegroundColor = ConsoleColor.Magenta;
        WriteLine("{0}'s Gross Income Was {1}.", workerLeast, workerGrossIncomeLeast.ToString("C"));
        WriteLine("{0}'s Regular Pay Was {1}.", workerLeast, workerRegularPayLeast.ToString("C")); //Output For LEAST
        WriteLine("{0}'s Overtime Pay Was {1}.", workerLeast, workerOverTimeLeast.ToString("C"));
        ForegroundColor = ConsoleColor.Cyan;
        WriteLine("\nThe Worker That Earned The Most Is {0}.", workerMost);
        WriteLine("-----------------------------");
        ForegroundColor = ConsoleColor.DarkGray;
        WriteLine("{0}'s Gross Income Was {1}.", workerMost, workerGrossIncomeMost.ToString("C"));
        WriteLine("{0}'s Regular Pay Was {1}.", workerMost, workerRegularPayMost.ToString("C"));   //Output For MOST
        WriteLine("{0}'s Overtime Pay Was {1}.", workerMost, workerOverTimeMost.ToString("C"));
        ForegroundColor = ConsoleColor.Red;
        WriteLine("\nPress Enter To Exit! \nThank You!");
        ReadLine();
    }
}
</code>```

here is where i think the issue is..

```<code>for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            if (workerWeeklyHours[i] > HOURS_OVERTIME)                                                    //If Hours # is > 40.
            {
                workerOvertimeHours[i] = workerWeeklyHours[i] - HOURS_OVERTIME;
                workerOvertimePay[i] = workerOvertimeHours[i] * (workerWages[i] * OVERTIME_PAY_DIFF);
                workerGrossIncome[i] = workerOvertimePay[i] + workersRegularPay[i];
            }
            else
            {
                workersRegularPay[i] = workerWeeklyHours[i] * workerWages[i];
                workerGrossIncome[i] = workerWeeklyHours[i] * workerWages[i];
                workerStateTaxAmount[i] = workerGrossIncome[i] * STATE_TAX_DEDUCTION;
                workerFederalTaxAmount[i] = workerGrossIncome[i] * FEDERAL_TAX_DEDUCTION;
                workerNetIncome[i] = workerGrossIncome[i] - workerFederalTaxAmount[i] - workerStateTaxAmount[i];
                workerOvertimePay[i] = 0;
                workerOvertimeHours[i] = 0;
            }
</code>```

Somewhere a Logic issue
Output Is:Output end only missing console inputs and first output

答:
C# is an object-oriented programming language.  You need to create a class to encapsulate all of this data and make sense of it.  Having all of these loosely-related arrays is a mess - your code is not reusable, data can't be changed easily if a worker gets a raise or a different schedule, and frankly is confusing to look and and to input data into.

It is better to create a Worker class like this (right-click on your project in your Solution Explorer, click Add, click Class to create a new class file and call it "Worker.cs"):

```<code>public class Worker
{
    // properties contain data for each worker
    public string Name { get; set; }
    public decimal HoursPerWeek { get; set; }
    public decimal HourlyPay { get; set; }

    // this is your constructor.  Set your variables to initial values here
    public Worker(string WorkerName, decimal WorkerHoursPerWeek, decimal WorkerHourlyPay)
    {
        this.Name = WorkerName;
        this.HoursPerWeek = WorkerHoursPerWeek;
        this.HourlyPay = WorkerHourlyPay;
    }

    // use methods to return any calculated values
    public decimal GetWeeklyPay()
    {
        decimal NormalHours;

        if (HoursPerWeek <= 40.0)
            NormalHours = HoursPerWeek;
        else
            NormalHours = 40.0M;

        decimal OverTimeHours;

        if (HoursPerWeek <= 40.0)
            OverTimeHours = 0.0M;
        else
            OverTimeHours = HoursPerWeek - 40.0;

        // hourly pay up to 40 hours, 1.5 times hourly pay for overtime
        return (NormalHours * HourlyPay) + (1.5M * (OverTimeHours * HourlyPay));
    }
}
</code>```

Now that you have your worker class, instead of populating a dozen confusing arrays, you just write a program to create instances of your worker class like this:

```<code>// in your Program.cs, create instances of your worker class like this:
List<Worker> workers = new List<Worker>();

for (int i = 0; i < MAX_LIST_VALUE; i++)
{
    Console.WriteLine("Enter name for employee:");
    string name = Console.ReadLine();

    Console.WriteLine("Enter hours per week:");
    decimal hours = Decimal.Parse(Console.ReadLine());

    Console.WriteLine("Enter hourly wage:");
    decimal wage = Decimal.Parse(Console.ReadLine());

    // this creates an instance of your worker class and adds it to the list
    workers.Add(new Worker(name, hours, wage));
}

// now you have a list of workers that you can sort using Linq or some other method:
var sortedWorkers = workers.OrderByDescending(w => w.GetWeeklyPay());

// and you can output them in order from most pay to least:
foreach (Worker w in sortedWorkers)
{
    Console.WriteLine("Worker " + w.Name + " makes " + w.GetWeeklyPay().ToString() + " dollars per week!");
}
</code>```

Body:
Here is the full source code It is not outputting the correct persons that make the most and the least. My best guess is the if statement inside the loop for calculations on pay if the person makes works over 40 hours. Code is simple learning C#. What is the best way to fix this.... sorry I know this is a probably a simple issue i'm missing. COMMENTS TO LABEL

{
class Program
{
    const double FEDERAL_TAX_DEDUCTION = .10; //Federal Tax 10% of Gross Income
    const double STATE_TAX_DEDUCTION = .05;   //State Tax 5% of Gross Income
    const int    HOURS_OVERTIME = 40;         //# of Hours Needed For Overtime Pay Rate
    const double OVERTIME_PAY_DIFF = 1.5;     //150% of Normal Pay

    static void Main(string[] args)
    {
        int MAX_LIST_VALUE;  //How Many Workers There Are For Array Limit.

        Write("How Many Workers Are Currently Working? ");                  //Asks For User Input # Of Workers
        MAX_LIST_VALUE = Convert.ToInt32(ReadLine());

        string[] workerName = new string[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.Blue;
            WriteLine("Please Enter The Worker's Name: ");        //Asks For User Input For Worker's Names
            workerName[i] = ReadLine();
        }
        double[] workerWages = new double[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.DarkYellow;
            WriteLine("Please Enter " + workerName[i] + "'s Hourly Wage: "); //Asks For User Input For Worker's Wage
            workerWages[i] = Convert.ToDouble(ReadLine());
        }
        double[] workerWeeklyHours = new double[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.DarkCyan;
            Write("How Many Hours Has {0} Worked This Week? ", workerName[i]); //Asks For User Input For Hours Worked
            workerWeeklyHours[i] = Convert.ToDouble(ReadLine());
        }
        double[] workersRegularPay = new double[MAX_LIST_VALUE];
        double[] workerGrossIncome = new double[MAX_LIST_VALUE];
        double[] workerStateTaxAmount = new double[MAX_LIST_VALUE];                //All Calculation Arrays
        double[] workerFederalTaxAmount = new double[MAX_LIST_VALUE];
        double[] workerNetIncome = new double[MAX_LIST_VALUE];
        double[] workerOvertimeHours = new double[MAX_LIST_VALUE];
        double[] workerOvertimePay = new double[MAX_LIST_VALUE];
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            if (workerWeeklyHours[i] > HOURS_OVERTIME)                                                    //If Hours # is > 40.
            {
                workerOvertimeHours[i] = workerWeeklyHours[i] - HOURS_OVERTIME;
                workerOvertimePay[i] = workerOvertimeHours[i] * (workerWages[i] * OVERTIME_PAY_DIFF);
                workerGrossIncome[i] = workerOvertimePay[i] + workersRegularPay[i];
            }
            else
            {
                workersRegularPay[i] = workerWeeklyHours[i] * workerWages[i];
                workerGrossIncome[i] = workerWeeklyHours[i] * workerWages[i];
                workerStateTaxAmount[i] = workerGrossIncome[i] * STATE_TAX_DEDUCTION;
                workerFederalTaxAmount[i] = workerGrossIncome[i] * FEDERAL_TAX_DEDUCTION;
                workerNetIncome[i] = workerGrossIncome[i] - workerFederalTaxAmount[i] - workerStateTaxAmount[i];
                workerOvertimePay[i] = 0;
                workerOvertimeHours[i] = 0;
            }
        }
        ForegroundColor = ConsoleColor.Blue;
        WriteLine("\nNAMES ARE BLUE.");
        ForegroundColor = ConsoleColor.DarkYellow;
        WriteLine("HOURLY WAGES ARE DARK YELLOW.");
        ForegroundColor = ConsoleColor.DarkCyan;
        WriteLine("HOURS WORKED ARE DARK CYAN.");
        ForegroundColor = ConsoleColor.Green;
        WriteLine("NET INCOMES ARE GREEN.");
        ForegroundColor = ConsoleColor.Red;
        WriteLine("-----------------------------");
        WriteLine("There Are " + MAX_LIST_VALUE + " Workers!");  //Echo Of All Data Entered & Calculated For Workers
        for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            ForegroundColor = ConsoleColor.Blue;
            WriteLine("\nWorker's Name: " + workerName[i]);
            WriteLine("-----------------------------");
            ForegroundColor = ConsoleColor.DarkYellow;
            WriteLine(workerName[i] + "'s Hourly Wage: " + workerWages[i].ToString("C"));
            ForegroundColor = ConsoleColor.DarkCyan;
            WriteLine(workerName[i] + "'s Hours Worked This Week: " + workerWeeklyHours[i]);
            ForegroundColor = ConsoleColor.White;
            WriteLine(workerName[i] + "'s Regular Pay: " + workersRegularPay[i].ToString("C"));
            WriteLine(workerName[i] + "'s Gross Income Pay: " + workerGrossIncome[i].ToString("C"));
            WriteLine(workerName[i] + "'s State Tax Amount: " + workerStateTaxAmount[i].ToString("C"));
            WriteLine(workerName[i] + "'s Federal Tax Amount: " + workerFederalTaxAmount[i].ToString("C"));
            ForegroundColor = ConsoleColor.Green;
            WriteLine(workerName[i] + "'s Net Income: " + workerNetIncome[i].ToString("C"));
            WriteLine(workerName[i] + "'s Overtime Hours: " + workerOvertimeHours[i]);
            WriteLine(workerName[i] + "'s Overtime Pay (if any): " + workerOvertimePay[i].ToString("C"));
        }
        ForegroundColor = ConsoleColor.Red;
        WriteLine("\nPress Enter To Continue For The Worker's That Earned The Least & The Most.");
        ReadLine();

        int minIndex = 0;
        string workerLeast = "null";
        double workerRegularPayLeast = 0,
               workerGrossIncomeLeast = 0,
               workerOverTimeLeast = 0;
        int maxIndex = 0;
        string workerMost = "null";
        double workerRegularPayMost = 0,
               workerGrossIncomeMost = 0,
               workerOverTimeMost = 0;

        for (int i = 0; i < workerGrossIncome.Length; i++)         //Calculation For Worker That Made The LEAST
            if (workerGrossIncome[i] < workerGrossIncome[minIndex])
            {
                minIndex = i;
                workerLeast = workerName[i];
                workerRegularPayLeast = workersRegularPay[i];
                workerGrossIncomeLeast = workerGrossIncome[i];
                workerOverTimeLeast = workerOvertimePay[i];
            }
        for (int i = 0; i < workerGrossIncome.Length; i++)         //Calculation For Worker That Made The MOST
            if (workerGrossIncome[i] >= workerGrossIncome[maxIndex])
            {
                maxIndex = i;
                workerMost = workerName[i];
                workerRegularPayMost = workersRegularPay[i];
                workerGrossIncomeMost = workerGrossIncome[i];
                workerOverTimeLeast = workerOvertimePay[i];
            }
        ForegroundColor = ConsoleColor.Green;
        WriteLine("\nThe Worker That Earned The Least Is {0}.", workerLeast);
        WriteLine("-----------------------------");
        ForegroundColor = ConsoleColor.Magenta;
        WriteLine("{0}'s Gross Income Was {1}.", workerLeast, workerGrossIncomeLeast.ToString("C"));
        WriteLine("{0}'s Regular Pay Was {1}.", workerLeast, workerRegularPayLeast.ToString("C")); //Output For LEAST
        WriteLine("{0}'s Overtime Pay Was {1}.", workerLeast, workerOverTimeLeast.ToString("C"));
        ForegroundColor = ConsoleColor.Cyan;
        WriteLine("\nThe Worker That Earned The Most Is {0}.", workerMost);
        WriteLine("-----------------------------");
        ForegroundColor = ConsoleColor.DarkGray;
        WriteLine("{0}'s Gross Income Was {1}.", workerMost, workerGrossIncomeMost.ToString("C"));
        WriteLine("{0}'s Regular Pay Was {1}.", workerMost, workerRegularPayMost.ToString("C"));   //Output For MOST
        WriteLine("{0}'s Overtime Pay Was {1}.", workerMost, workerOverTimeMost.ToString("C"));
        ForegroundColor = ConsoleColor.Red;
        WriteLine("\nPress Enter To Exit! \nThank You!");
        ReadLine();
    }
}

here is where i think the issue is..

for (int i = 0; i < MAX_LIST_VALUE; i++)
        {
            if (workerWeeklyHours[i] > HOURS_OVERTIME)                                                    //If Hours # is > 40.
            {
                workerOvertimeHours[i] = workerWeeklyHours[i] - HOURS_OVERTIME;
                workerOvertimePay[i] = workerOvertimeHours[i] * (workerWages[i] * OVERTIME_PAY_DIFF);
                workerGrossIncome[i] = workerOvertimePay[i] + workersRegularPay[i];
            }
            else
            {
                workersRegularPay[i] = workerWeeklyHours[i] * workerWages[i];
                workerGrossIncome[i] = workerWeeklyHours[i] * workerWages[i];
                workerStateTaxAmount[i] = workerGrossIncome[i] * STATE_TAX_DEDUCTION;
                workerFederalTaxAmount[i] = workerGrossIncome[i] * FEDERAL_TAX_DEDUCTION;
                workerNetIncome[i] = workerGrossIncome[i] - workerFederalTaxAmount[i] - workerStateTaxAmount[i];
                workerOvertimePay[i] = 0;
                workerOvertimeHours[i] = 0;
            }

Somewhere a Logic issue
Output Is:Output end only missing console inputs and first output

Body:
C# is an object-oriented programming language.  You need to create a class to encapsulate all of this data and make sense of it.  Having all of these loosely-related arrays is a mess - your code is not reusable, data can't be changed easily if a worker gets a raise or a different schedule, and frankly is confusing to look and and to input data into.

It is better to create a Worker class like this (right-click on your project in your Solution Explorer, click Add, click Class to create a new class file and call it "Worker.cs"):

public class Worker
{
    // properties contain data for each worker
    public string Name { get; set; }
    public decimal HoursPerWeek { get; set; }
    public decimal HourlyPay { get; set; }

    // this is your constructor.  Set your variables to initial values here
    public Worker(string WorkerName, decimal WorkerHoursPerWeek, decimal WorkerHourlyPay)
    {
        this.Name = WorkerName;
        this.HoursPerWeek = WorkerHoursPerWeek;
        this.HourlyPay = WorkerHourlyPay;
    }

    // use methods to return any calculated values
    public decimal GetWeeklyPay()
    {
        decimal NormalHours;

        if (HoursPerWeek <= 40.0)
            NormalHours = HoursPerWeek;
        else
            NormalHours = 40.0M;

        decimal OverTimeHours;

        if (HoursPerWeek <= 40.0)
            OverTimeHours = 0.0M;
        else
            OverTimeHours = HoursPerWeek - 40.0;

        // hourly pay up to 40 hours, 1.5 times hourly pay for overtime
        return (NormalHours * HourlyPay) + (1.5M * (OverTimeHours * HourlyPay));
    }
}

Now that you have your worker class, instead of populating a dozen confusing arrays, you just write a program to create instances of your worker class like this:

// in your Program.cs, create instances of your worker class like this:
List<Worker> workers = new List<Worker>();

for (int i = 0; i < MAX_LIST_VALUE; i++)
{
    Console.WriteLine("Enter name for employee:");
    string name = Console.ReadLine();

    Console.WriteLine("Enter hours per week:");
    decimal hours = Decimal.Parse(Console.ReadLine());

    Console.WriteLine("Enter hourly wage:");
    decimal wage = Decimal.Parse(Console.ReadLine());

    // this creates an instance of your worker class and adds it to the list
    workers.Add(new Worker(name, hours, wage));
}

// now you have a list of workers that you can sort using Linq or some other method:
var sortedWorkers = workers.OrderByDescending(w => w.GetWeeklyPay());

// and you can output them in order from most pay to least:
foreach (Worker w in sortedWorkers)
{
    Console.WriteLine("Worker " + w.Name + " makes " + w.GetWeeklyPay().ToString() + " dollars per week!");
}


来源: stackexchange

问:
How to add columnname to value in bigquery
I have a bigquery table that contains 3 "code" fields.  some of these fields are used to look up against a code table.  Assume the table looks like this:

```<code>data table:
    id    code1    code2     code3     data1
    1       Y        3         A        IA
    2       Y        2         B        IB
    3       N        5         C        IC
</code>```

in order to perform the lookup, I have to concat the field_name to the value, delimited by a colon.  I cannot hardcode the column name.  using big query, is there a way to use the table object to infer the column name within the select statement?

for example:

```<code>select * from code_table join data_table where code1 = code.code_values
the value of code1 coming out is 'code1:Y'  not 'Y'.
</code>```

I'm wondering if there's a way to inject the column_name dynamically in the code1 value as it's going out to the code_table.

UPDATE 1:

Here's an example output from data_table to join against code_table:

```<code>1, code1:Y, code2:3, code3:A, IA
2, code1:Y, code2:2, code3:B, IB
3, code1:N, code2:5, code3:C, IC
</code>```

Thanks

答:
#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 AS id, 'Y' AS code1, 3 AS code2, 'A' AS code3, 'IA' AS data1 UNION ALL
  SELECT 2, 'Y', 2, 'B', 'IB' UNION ALL
  SELECT 3, 'N', 5, 'C', 'IC'
)
SELECT
  id,
  MAX(IF(col = 1, val, NULL)) AS col1,
  MAX(IF(col = 2, val, NULL)) AS col2,
  MAX(IF(col = 3, val, NULL)) AS col3,
  data1
FROM `project.dataset.table` AS t, UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t), r'"|{|}', ''))) AS val WITH OFFSET col
WHERE col BETWEEN 1 AND 3
GROUP BY id, data1
ORDER BY id
```

<p>output as below   </p>

<pre class="lang-sql prettyprint-override"><code>id  col1        col2        col3        data1
1   code1:Y     code2:3     code3:A     IA
2   code1:Y     code2:2     code3:B     IB
3   code1:N     code2:5     code3:C     IC
</code>```

with above query you just need to know number of code columns so if it is 5 (for example) you need to add two more in SELECT and change BETWEEN 1 AND 3 to BETWEEN 1 AND 5

ContentLicense: CC BY-SA 3.0

Body:
I have a bigquery table that contains 3 "code" fields.  some of these fields are used to look up against a code table.  Assume the table looks like this:

data table:
    id    code1    code2     code3     data1
    1       Y        3         A        IA
    2       Y        2         B        IB
    3       N        5         C        IC

in order to perform the lookup, I have to concat the field_name to the value, delimited by a colon.  I cannot hardcode the column name.  using big query, is there a way to use the table object to infer the column name within the select statement?

for example:

select * from code_table join data_table where code1 = code.code_values
the value of code1 coming out is 'code1:Y'  not 'Y'.

I'm wondering if there's a way to inject the column_name dynamically in the code1 value as it's going out to the code_table.

UPDATE 1:

Here's an example output from data_table to join against code_table:

1, code1:Y, code2:3, code3:A, IA
2, code1:Y, code2:2, code3:B, IB
3, code1:N, code2:5, code3:C, IC

Thanks

Body:
#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 AS id, 'Y' AS code1, 3 AS code2, 'A' AS code3, 'IA' AS data1 UNION ALL
  SELECT 2, 'Y', 2, 'B', 'IB' UNION ALL
  SELECT 3, 'N', 5, 'C', 'IC'
)
SELECT
  id,
  MAX(IF(col = 1, val, NULL)) AS col1,
  MAX(IF(col = 2, val, NULL)) AS col2,
  MAX(IF(col = 3, val, NULL)) AS col3,
  data1
FROM `project.dataset.table` AS t, UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t), r'"|{|}', ''))) AS val WITH OFFSET col
WHERE col BETWEEN 1 AND 3
GROUP BY id, data1
ORDER BY id

output as below

id  col1        col2        col3        data1
1   code1:Y     code2:3     code3:A     IA
2   code1:Y     code2:2     code3:B     IB
3   code1:N     code2:5     code3:C     IC

with above query you just need to know number of code columns so if it is 5 (for example) you need to add two more in SELECT and change BETWEEN 1 AND 3 to BETWEEN 1 AND 5


问:
How to test socket.io events being called with sinon.spy
First of all, I'm trying to test the second time a function being called returns the correct value. To be more specific, I'm trying to test the second time an event is received by socket.on() returns the correct value.

I know that Sinon.spy() can detect whether a function being called or not. But it seems not working with socket.io events.

I'm trying to test for example,

```<code>var socketio = io.connect(someUrl);
socketio.on(eventName, cb);
</code>```

if the 'eventName' is called. I tried

```<code>var spy = sinon.spy(socketio, 'on');
assert(spy.withArgs(eventName).called);
</code>```

But it says it's never being called.

Furthermore, what if I'd like to test the data in the callback function is right or not, for example

```<code>var socketio = io.connect(someUrl);
socketio.on(eventName, function(data) {
    data.should.equal(something);
});
</code>```

Is it possible to test that?

Update:

I solved the problem by adding a count in callback

```<code>var count = 0;
socketio.on(eventName, function(data) {
    count++;
    if(count === 2) {
        data.should.equal(something)
    }
}
</code>```

But I think this is a hacky way, is there any standard/smart way to do it(if possible using sinon)?

答:
You don't want to spy on on -- that's only called once, at the time you set up the listener. (Unless you actually want to spy to see if the listeners are being set up at all, and don't care if they're actually used. That doesn't appear to be what you want here.)

Instead, you want to spy on the cb callback function, to see if and how it runs.

```<code>var callbackSpy = sinon.spy(cb);
</code>```

Then, pass that spy in as the callback:

```<code>socketio.on(eventName, callbackSpy);
</code>```

And test if the callback was ever run with the desired argument value:

```<code>assert(callbackSpy.calledWith(something));
</code>```

Body:
First of all, I'm trying to test the second time a function being called returns the correct value. To be more specific, I'm trying to test the second time an event is received by socket.on() returns the correct value.

I know that Sinon.spy() can detect whether a function being called or not. But it seems not working with socket.io events.

I'm trying to test for example,

var socketio = io.connect(someUrl);
socketio.on(eventName, cb);

if the 'eventName' is called. I tried

var spy = sinon.spy(socketio, 'on');
assert(spy.withArgs(eventName).called);

But it says it's never being called.

Furthermore, what if I'd like to test the data in the callback function is right or not, for example

var socketio = io.connect(someUrl);
socketio.on(eventName, function(data) {
    data.should.equal(something);
});

Is it possible to test that?

Update:

I solved the problem by adding a count in callback

var count = 0;
socketio.on(eventName, function(data) {
    count++;
    if(count === 2) {
        data.should.equal(something)
    }
}

But I think this is a hacky way, is there any standard/smart way to do it(if possible using sinon)?

Body:
You don't want to spy on on -- that's only called once, at the time you set up the listener. (Unless you actually want to spy to see if the listeners are being set up at all, and don't care if they're actually used. That doesn't appear to be what you want here.)

Instead, you want to spy on the cb callback function, to see if and how it runs.

var callbackSpy = sinon.spy(cb);

Then, pass that spy in as the callback:

socketio.on(eventName, callbackSpy);

And test if the callback was ever run with the desired argument value:

assert(callbackSpy.calledWith(something));


问:
Angular ngClass trigger change detection error when binded to ngModel validation
I'm trying to set the color of a label in Angular 2 depending on its email-validation like this:

```<code><input type="email" name="email" [(ngModel)]="email" email #currentEmail="ngModel" [ngClass]="currentEmail.invalid ? 'error' : 'none'">
</code>```

It works as expected on my page, however in Visual Studio Code I get the following error message:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'error'. Current value: 'none'.

So my questions are:

Why does this message show up?

Whats the right approach to do this task?

答:
Why does this message show up?

You can find a good explaination of why in this issue

This is not a bug, it's a feature of dev mode working as intended. Calling enableProdMode( ) - when bootstrapping the app prevents the exception from being thrown.

That said, it's being thrown for good reason: In short, after every round of change detection, dev mode immediately performs a second round to verify that no bindings have changed since the end of the first, as this would indicate that changes are being caused by change detection itself.

In your plunk, you have the binding [attr.spinner]=isLoading, and isLoading changes as a result of your call to this.load(), which occurs when ngAfterViewInit is fired, which happens as a part of the initial change detection turn. That in itself isn't problematic though - the problem is that this.load() changes a binding but does not trigger a new round of change detection, which means that this binding will not be updated until some future round of change detection.

Whats the right approach to do this task?

Simply replace [ngClass] with [class]. I don't know why, but when trying to reproduce your issue in a plunker, I found out that [class] does not trigger the error.

Edit : use ng-invalid class

You can also style your element based on the angular class ng-invalid.

See this plunker

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to set the color of a label in Angular 2 depending on its email-validation like this:

<input type="email" name="email" [(ngModel)]="email" email #currentEmail="ngModel" [ngClass]="currentEmail.invalid ? 'error' : 'none'">

It works as expected on my page, however in Visual Studio Code I get the following error message:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'error'. Current value: 'none'.

So my questions are:

Why does this message show up?

Whats the right approach to do this task?


问:
Change Domain Name from localhost to Actual Domain
I just completed my theme with content development in Xamp (Mac). I am working on WordPress Framework and all theme and content is ready and access using http://localhost/doctorweb/

My actual domain name is doctorweb.co.

Now I want to upload all theme + widgets + content on my actual domain. How is this possible to use all the localhost development change into actual domain name ?

答: That config is actually stored on your database when you install/create wordpress database. You can change it manually through mysql console or using phpadmin. It's located on wp_options table, you're gonna see two options that defines it: home and siteurl. Those are the ones you gotta change. Hope this helps, good luck


问:
Run Node Red as SU on boot
I would like to use Port 502 for my ModBus Server Flow, however, I can only do this if I run "sudo node-red-start"

I have it set to run as a service using "sudo systemctl enable nodered.service"
However, this only seems to execute it as a normal user.

Thanks

答:
There is another way to the one @knolleary has suggested, which is to allow the pi user to open low ports. This can be done by running the following command:

```<code>sudo setcap 'cap_net_bind_service=+ep' `which node`
</code>```

This will allow the node binary bind to ports lower than 1024 as any user.

Be aware that this could be a security issue as it will allow any user to run NodeJS app that can then pretend to be a system service (e.g. SSH)

Title: Run Node Red as SU on boot

Body:
There is another way to the one @knolleary has suggested, which is to allow the pi user to open low ports. This can be done by running the following command:

sudo setcap 'cap_net_bind_service=+ep' `which node`

This will allow the node binary bind to ports lower than 1024 as any user.

Be aware that this could be a security issue as it will allow any user to run NodeJS app that can then pretend to be a system service (e.g. SSH)


问:
Android Studio on SSD drive
I just have a SSD drive which is 240 GB. I also have a mechanic drive which is 1 TB.

Im gonna install Android Studio to SSD.

The question is should i install SDK too on SSD ?

is it gonna improve Android Studio performance ?

答:
Machine Specs: Alienware-i7 7820HK|16GB RAM|256GB PCie SSD|1TB HDD

Software Config: Android Studio in SSD|SDK in HDD|Project Folder in HDD

Clock Time to load Android Studio: 9s

Clock Time to create a new empty project: 20s till Gradle Build Finished

Clock Time to open an empty project: Less than 5s till Gradle Build Finished

Clock Time to open Android Studio; create a new empty project: 40s till Gradle Build Finished

Title: Android Studio on SSD drive


问:
Reusable code soap client laravel
I have different functions that use the same soap client in laravel:
The duplicate code for the soapclient in these functions seems wrong.
I tried with a trait file but I don't seem to get it working that way.

```<code> public function getStaff()
    {
        // INITIALISEER DE SOAP CLIENT
        $webservicesPwd = "apipwd";
        $soap = new SoapClient('https://apiserver.com');

        // HAAL STUDENTEN OP VIA API CALL
        $result = $soap->apiFunction($webservicesPwd,2,1);

        // INDIEN RESULTAAT NIET CORRECT
        if(is_int($result)) {

           throw new \Exception($errorMessage);
        }
</code>```

And

```<code>public function getStudents()
    {
          // INITIALISEER DE SOAP CLIENT
        $webservicesPwd = "apipwd";
        $soap = new SoapClient('https://apiserver.com');

        // HAAL STUDENTEN OP VIA API CALL
        $result = $this->soap-someOtherApiFunction($this->webservicesPwd,3,1);

        // INDIEN RESULTAAT NIET CORRECT
      if(is_int($result)) {

           throw new \Exception($errorMessage);
        }

        dd($result);
    }
</code>```

答:
Create a new class:</p>

```<code>class ApiNameClient {
    protected $soapClient;

    protected $webservicesPwd;

    public function __construct() {
    // initialize $soapClient and $webservicesPwd here
    }

    public function getStudents() {
        $result = $this->soapClient->myFirstAction($this->webservicesPwd,3,1);

        return $this->defendInteger($result);
    }

    protected function defendInteger($value) {
        if(is_int($value)) {
            throw new \Exception($errorMessage);
        }
        return $value;
    }
}
</code>```

Title: Reusable code soap client laravel

Body:
I have different functions that use the same soap client in laravel:
The duplicate code for the soapclient in these functions seems wrong.
I tried with a trait file but I don't seem to get it working that way.

 public function getStaff()
    {
        // INITIALISEER DE SOAP CLIENT
        $webservicesPwd = "apipwd";
        $soap = new SoapClient('https://apiserver.com');

        // HAAL STUDENTEN OP VIA API CALL
        $result = $soap->apiFunction($webservicesPwd,2,1);

        // INDIEN RESULTAAT NIET CORRECT
        if(is_int($result)) {

           throw new \Exception($errorMessage);
        }

And

public function getStudents()
    {
          // INITIALISEER DE SOAP CLIENT
        $webservicesPwd = "apipwd";
        $soap = new SoapClient('https://apiserver.com');

        // HAAL STUDENTEN OP VIA API CALL
        $result = $this->soap-someOtherApiFunction($this->webservicesPwd,3,1);

        // INDIEN RESULTAAT NIET CORRECT
      if(is_int($result)) {

           throw new \Exception($errorMessage);
        }

        dd($result);
    }

Body:
Create a new class:

class ApiNameClient {
    protected $soapClient;

    protected $webservicesPwd;

    public function __construct() {
    // initialize $soapClient and $webservicesPwd here
    }

    public function getStudents() {
        $result = $this->soapClient->myFirstAction($this->webservicesPwd,3,1);

        return $this->defendInteger($result);
    }

    protected function defendInteger($value) {
        if(is_int($value)) {
            throw new \Exception($errorMessage);
        }
        return $value;
    }
}


问:
java string replace ignore parts of string not in brackets
I have a list string below

```<code>Hello 123, [Derp]
         , [Derpa]
         , [derpb]
</code>```

I tried...

```<code>//loop n bufferedreader stuff
string a = b.replaceAll("[Hello 123\\[\\]\\ ]", "")
</code>```

what i got

```<code>Drp
Drpa
Drpb
</code>```

What i want

```<code>Derp
Derpa
Derpb
</code>```

I also tried to declare 2 bufferedreaders
the first one to hardcode ignore "Hellow 123" out of the string
and 2nd one without the hardcode
but same problem still occurs

答:
Instead of

```<code>String a = b.replaceAll("[Hello 123\\[\\]\\ ]", "")
</code>```

write

```<code>String a = b.replaceAll("[\\[\\]\\ ]", "");
a = a.replace("Hello", "");
a = a.replace("123,", "");
</code>```

Body:
I have a list string below

Hello 123, [Derp]
         , [Derpa]
         , [derpb]

I tried...

//loop n bufferedreader stuff
string a = b.replaceAll("[Hello 123\\[\\]\\ ]", "")

what i got

Drp
Drpa
Drpb

What i want

Derp
Derpa
Derpb

I also tried to declare 2 bufferedreaders
the first one to hardcode ignore "Hellow 123" out of the string
and 2nd one without the hardcode
but same problem still occurs

Body:
Instead of

String a = b.replaceAll("[Hello 123\\[\\]\\ ]", "")

write

String a = b.replaceAll("[\\[\\]\\ ]", "");
a = a.replace("Hello", "");
a = a.replace("123,", "");


问:
Is it possible to have multiple STDIN streams?
I'm hoping to connect two USB barcode scanners to a single computer, allowing two people to scan ticket barcodes simultaneously.  If both people scan at the same time, however, the input from STDIN will get messy.

Is there a way to set up different STDIN streams, each tied to a specific USB port?  The console script is in Ruby, though pointers in any language would be much appreciated.

答: To answer your question directly, there is no way to have more than one STDIN.  You're best bet would be to read the data from a file (I would think you should have a character device or something for this scanner)</p>

ContentLicense: CC BY-SA 2.5


问:
Spring maven - run specific tests (via annotations or maven profile)
Using a Spring maven context, I would like to run specific tests based on a maven profile. I would like to have an easy way of tagging the test groups. If possible I would like to use the annotations.
Which options are there, like maven command line parameters, maven profiles specification, etc.

Say I have the following tests:

Example:

```<code>// annotation("integration")
public class GeopointFormatterTest {
    @Test
    public void testIntegration1() {  ...  }
    @Test
    public void testIntegration2() {  ...  }
</code>```

Annotations like @Profile (which is for creating beans) and @ActiveProfile (which is for selecting specific profiles for creating beans) cannot be used for selecting tests, of course. All tests just run for statements like:

mvn clean install -Pdevelopment

mvn clean install -Pdevelopment -Dspring.profiles.active=acceptance

mvn clean install -Pdevelopment -Dspring.profiles.active=integration

As suggested, I used also @IfProfileValue. This is a good way for selecting tests based on system property values. System property values can be overruled by a CustomProfileValueSource class, like in: @ProfileValueSourceConfiguration(CustomProfileValueSource.class)

EDIT and ALTERNATIVE

The GREAT answers below focus on JUnit's @Category mechanism. Thanks to all!

A different approach is via these steps: [1] set a property within a maven profile and [2] use the property to skip tests via the  of the standard surefire test plugin.

[1] Setting the properties via a profile:

```<code><profiles>
    <profile>
        <id>integrationtests</id>
        <properties>
            <integration.skip>false</integration.skip>
            <acceptance.skip>true</acceptance.skip>
        </properties>
    </profile>
    ... other profiles
</code>```

[2] Using the properties in the surefire test plugin to skip tests.

```<code><build>
   <plugins>
      <plugin>
         <!-- Run the integration test-->
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>${surefire.plugin.version}</version>
         <configuration>
            <skipTests>${acceptance.skip}</skipTests>
</code>```

Start in maven: mvn clean install –Pintegrationtests

答:
We did solved categorization of junit in the following steps.

I did create a project for you in github.
https://github.com/djaganathan/unit-test-samples

Caveat:- Junit Categorization packages still says as experimental.

1) Created a category of interfaces

```<code>

    /**
     * This interface used to categories Junit Test
     * those Tests will be executed during bamboo build run
     */
    public interface ReleaseTest {
    }

</code>```

2) Tagged the unit testcases with the category you want

```<code>

    import org.junit.Test;
    import org.junit.experimental.categories.Category;
    import org.junit.internal.runners.JUnit4ClassRunner;
    import org.junit.runner.RunWith;

    import com.github.djaganathan.unit.test.category.ReleaseTest;

    @RunWith(JUnit4ClassRunner.class)
    public class GeneralTest {

        @Test
        @Category(value={ReleaseTest.class})
        public void doTestForRelease(){}

        @Test
        public void doTestForDev(){}

    }

</code>```

3) Create profile in maven and attach to it

4) Run the command as mvn test -PreleaseTest

Body:
Using a Spring maven context, I would like to run specific tests based on a maven profile. I would like to have an easy way of tagging the test groups. If possible I would like to use the annotations.
Which options are there, like maven command line parameters, maven profiles specification, etc.

Say I have the following tests:

Example:

// annotation("integration")
public class GeopointFormatterTest {
    @Test
    public void testIntegration1() {  ...  }
    @Test
    public void testIntegration2() {  ...  }

Annotations like @Profile (which is for creating beans) and @ActiveProfile (which is for selecting specific profiles for creating beans) cannot be used for selecting tests, of course. All tests just run for statements like:

mvn clean install -Pdevelopment

mvn clean install -Pdevelopment -Dspring.profiles.active=acceptance

mvn clean install -Pdevelopment -Dspring.profiles.active=integration

As suggested, I used also @IfProfileValue. This is a good way for selecting tests based on system property values. System property values can be overruled by a CustomProfileValueSource class, like in: @ProfileValueSourceConfiguration(CustomProfileValueSource.class)

EDIT and ALTERNATIVE

The GREAT answers below focus on JUnit's @Category mechanism. Thanks to all!

A different approach is via these steps: [1] set a property within a maven profile and [2] use the property to skip tests via the  of the standard surefire test plugin.

[1] Setting the properties via a profile:

<profiles>
    <profile>
        <id>integrationtests</id>
        <properties>
            <integration.skip>false</integration.skip>
            <acceptance.skip>true</acceptance.skip>
        </properties>
    </profile>
    ... other profiles

[2] Using the properties in the surefire test plugin to skip tests.

<build>
   <plugins>
      <plugin>

         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>${surefire.plugin.version}</version>
         <configuration>
            <skipTests>${acceptance.skip}</skipTests>

Start in maven: mvn clean install –Pintegrationtests

Body:
We did solved categorization of junit in the following steps.

I did create a project for you in github.
https://github.com/djaganathan/unit-test-samples

Caveat:- Junit Categorization packages still says as experimental.

1) Created a category of interfaces

    /**
     * This interface used to categories Junit Test
     * those Tests will be executed during bamboo build run
     */
    public interface ReleaseTest {
    }

2) Tagged the unit testcases with the category you want

    import org.junit.Test;
    import org.junit.experimental.categories.Category;
    import org.junit.internal.runners.JUnit4ClassRunner;
    import org.junit.runner.RunWith;

    import com.github.djaganathan.unit.test.category.ReleaseTest;

    @RunWith(JUnit4ClassRunner.class)
    public class GeneralTest {

        @Test
        @Category(value={ReleaseTest.class})
        public void doTestForRelease(){}

        @Test
        public void doTestForDev(){}

    }

3) Create profile in maven and attach to it

4) Run the command as mvn test -PreleaseTest


问:
Scheme lambda and let errors
A beginner in scheme.. trying out the following code to test the equivalence of lambda and let

```<code>(lambda (x y)
  (+ x y)
  10
  (* x 2))

(let ((k 10)
      (y (* 2 k)))
  (+ k y))
</code>```

the output is

```<code>#<procedure>
. . k: undefined;
 cannot reference undefined identifier
>
</code>```

Any help would be appreciated

答:
The bindings in let cannot be used before the body of the let form. Thus you need to define k:

```<code>(define k 99)

(let ((k 10)
      (y (* 2 k))) ; the k here is not the one in the same `let`
  (+ k y))
; ==> 208
</code>```

let is just syntax sugar for a called anonymous procedure. It's equal to this:

```<code>((lambda (k y)
   (+ k y))
 10
 (* 2 k))
</code>```

With this syntax is perhaps more obvious that k cannot be the one assigned to 10? There is another syntax called let* and it lets you use the previous bindings:

```<code>(let* ((k 10)
       (y (* 2 k))) ; the k here is not the one in the same `let`
  (+ k y))
; ==> 30
</code>```

It's equal to nested anonymous procedure calls:

```<code>((lambda (k)
   ((lambda (y)
      (+ k y))
    (* 2 k)))
 10)
</code>```

Here it's easy to see the k in (* 2 k) is the one bound to 10.

Title: Scheme lambda and let errors

Body:
A beginner in scheme.. trying out the following code to test the equivalence of lambda and let

(lambda (x y)
  (+ x y)
  10
  (* x 2))

(let ((k 10)
      (y (* 2 k)))
  (+ k y))

the output is

#<procedure>
. . k: undefined;
 cannot reference undefined identifier
>

Any help would be appreciated

Body:
The bindings in let cannot be used before the body of the let form. Thus you need to define k:

(define k 99)

(let ((k 10)
      (y (* 2 k))) ; the k here is not the one in the same `let`
  (+ k y))
; ==> 208

let is just syntax sugar for a called anonymous procedure. It's equal to this:

((lambda (k y)
   (+ k y))
 10
 (* 2 k))

With this syntax is perhaps more obvious that k cannot be the one assigned to 10? There is another syntax called let* and it lets you use the previous bindings:

(let* ((k 10)
       (y (* 2 k))) ; the k here is not the one in the same `let`
  (+ k y))
; ==> 30

It's equal to nested anonymous procedure calls:

((lambda (k)
   ((lambda (y)
      (+ k y))
    (* 2 k)))
 10)

Here it's easy to see the k in (* 2 k) is the one bound to 10.


问:
Convert static object to Observable and forkjoin
I have an object and need to combine it with an observable.

The object looks like this:

obj1

```<code>let org1Obj = {"category": "1", "testkey": "testvalue"}
</code>```

The results with JSON.stringify of the observable looks like this:

obj2

```<code>[{"id":"51XXgI1w77VerovThbUV","question":"Sdad"},
 {"id":"FxjDsyLBGqtrBx1EHFyM","question":"exanoke"}]
</code>```

I then have an observable that fetches data and I'm thinking of using forkJoin to combine the two so I end up with the following result:

```<code>{"category": "1",
 "testkey": "testvalue",
 "questions": [
   {"name": "test1"},
   {"name": "test"}
 ]
}
</code>```

How do I make org1Obj into an observable so I can use forkJoin on it and how can I add the second observable to "questions": [result from observable]?

答:
This is possible with:

```<code>const observable1 = Observable.of(obj1);
return Observable.forkJoin(observable1, observable2).map(([obj1, obj2]) => {
  return Object.assign({}, obj1, { questions: obj2 }); // or so
});
</code>```

And less complicated and more performant way to do this is to skip forkJoin and map an observable to resulting object:

```<code>return observable2.map(obj2 => {
  return Object.assign({}, obj1, { questions: obj2 }); // or so
});
</code>```

Body:
I have an object and need to combine it with an observable.

The object looks like this:

obj1

let org1Obj = {"category": "1", "testkey": "testvalue"}

The results with JSON.stringify of the observable looks like this:

obj2

[{"id":"51XXgI1w77VerovThbUV","question":"Sdad"},
 {"id":"FxjDsyLBGqtrBx1EHFyM","question":"exanoke"}]

I then have an observable that fetches data and I'm thinking of using forkJoin to combine the two so I end up with the following result:

{"category": "1",
 "testkey": "testvalue",
 "questions": [
   {"name": "test1"},
   {"name": "test"}
 ]
}

How do I make org1Obj into an observable so I can use forkJoin on it and how can I add the second observable to "questions": [result from observable]?

Body:
This is possible with:

const observable1 = Observable.of(obj1);
return Observable.forkJoin(observable1, observable2).map(([obj1, obj2]) => {
  return Object.assign({}, obj1, { questions: obj2 }); // or so
});

And less complicated and more performant way to do this is to skip forkJoin and map an observable to resulting object:

return observable2.map(obj2 => {
  return Object.assign({}, obj1, { questions: obj2 }); // or so
});


问:
Firebase permission denied with correct auth data (apparently)
I have a very weird issue - I authenticate myself with firebase (by phone and link account with email/password credentials) and it works just fine (fetching data etc.).

When the app (for any reason) crahes for me I keep getting Permission denied, though Auth.auth().currentUser is not nil and apparently keeps all my credentials? Anyone encountered something like this?

Swift 4, Xcode 9.0, Firebase installed via pods

答:
what are the rules you using? the simple user auth rules would be like this: {
  "rules": {
    "users": {
      ".read": "false",
        ".write": "true",
      "$uid": {
        ".read": "auth.uid === $uid",
            ".write": "auth.uid === $uid"
        }
      }
  }
}

give it a try


问:
Setting up projects in WAMP
I am trying to setup a dev wamp server on my local machine so I can do some dev work without giving my boss a heart attack if something goes wrong.

I have wamp running and working just fine, the problem is the project I am working on was developed using <?php include $_SERVER['DOCUMENT_ROOT'].'/ for all the paths.

The Document root of the server is D:/wamp/www which is correct for the dev server.

Is there a way that I can setup a project so that the relative document root for that particular project would be d:/wamp/www/project

I've tried to use vhosts and aliases to no avail. When I setup the vhost everything for the project worked fine but it was the only site on localhost.

答:
You probably can do that with a script like this one:

```<code>$basePath = dirname(__FILE__); // assuming this script is in D:/wamp/www
$projectPath = preg_replace('#('.$basePath.'/[^/]+)/.*#i', '\\1', $_SERVER['PHP_SELF']);
$_SERVER['DOCUMENT_ROOT'] = $projectPath;
</code>```

The preg_replace line strips everything from the current script's path up to BASE + 1 segment. Then then the last line overwrites the current DOCUMENT_ROOT index from $_SERVER with the new path.

You can then set auto_prepend_file in php.ini:

```<code>auto_prepend_file = D:/wamp/www/prepend_script.php
</code>```

Or .htaccess (in D:/wamp/www):

```<code>php_value auto_prepend_file prepend_script.php
</code>```

Title: Setting up projects in WAMP

Body:
You probably can do that with a script like this one:

$basePath = dirname(__FILE__); // assuming this script is in D:/wamp/www
$projectPath = preg_replace('#('.$basePath.'/[^/]+)/.*#i', '\\1', $_SERVER['PHP_SELF']);
$_SERVER['DOCUMENT_ROOT'] = $projectPath;

The preg_replace line strips everything from the current script's path up to BASE + 1 segment. Then then the last line overwrites the current DOCUMENT_ROOT index from $_SERVER with the new path.

You can then set auto_prepend_file in php.ini:

auto_prepend_file = D:/wamp/www/prepend_script.php

Or .htaccess (in D:/wamp/www):

php_value auto_prepend_file prepend_script.php


问:
Use ramda `sequence` to traverse a dictionary
How can I use ramda's sequence to traverse a dictionary?

Given the following dictionary

```<code>cars = {color: ['yellow', 'red'], year: [2017], model: ['coup', 'sedan']}
</code>```

I'd like to produce the traversed result

```<code>all_cars = [
    {color: 'yellow', year: 2017, model: 'coup'},
    {color: 'yellow', year: 2017, model: 'sedan'},
    {color: 'red', year: 2017, model: 'coup'},
    {color: 'red', year: 2017, model: 'sedan'}
]
</code>```

Using R.sequence results in a list of an empty list

```<code>R.sequence(R.of, cars)
[[]]
</code>```

If I traverse a list instead of a dictionary it produces the correct cartesian product, but the results are (of course) lists instead of dictionaries.

```<code>R.sequence(R.of, [['yellow', 'red'], [2017], ['coup', 'sedan']])
[["yellow", 2017, "coup"], ["yellow", 2017, "sedan"], ["red", 2017, "coup"], ["red", 2017, "sedan"]]
</code>```

答:
I can think of two ways to do this, one involving sequence, and the other not.

This one uses your sequence(of) call above:

```<code>const convert = lift(map)(
  compose(zipObj, keys),
  compose(sequence(of), values)
)

const all_cars = convert(cars);
</code>```

The other was built by my usual technique of keep changing the output with one transformation after another until I get to what I want:

```<code>const combine = pipe(
  toPairs,
  map(apply(useWith(map, [objOf, identity]))),
  reduce(xprod, [[]]),
  map(flatten),
  map(mergeAll)
)

const all_cars = combine(cars)
</code>```

This might be made a little clearer by introducing a crossproduct across multiple lists:

```<code>const xproduct = reduce(pipe(xprod, map(unnest)), [[]])

const combine = pipe(
  toPairs,
  map(apply(useWith(map, [objOf, identity]))),
  xproduct,
  map(mergeAll)
)
</code>```

The second version is what I came up with on first trying the problem.  Then when I looked to see what you'd tried, I got that first version.  That first version looks cleaner to me, although most of the individual steps in the second one are trivial.  But since there is one non-trivial step in there, the first one seems an overall winner.

You can see the first or the second on the Ramda REPL.

Body:
How can I use ramda's sequence to traverse a dictionary?

Given the following dictionary

cars = {color: ['yellow', 'red'], year: [2017], model: ['coup', 'sedan']}

I'd like to produce the traversed result

all_cars = [
    {color: 'yellow', year: 2017, model: 'coup'},
    {color: 'yellow', year: 2017, model: 'sedan'},
    {color: 'red', year: 2017, model: 'coup'},
    {color: 'red', year: 2017, model: 'sedan'}
]

Using R.sequence results in a list of an empty list

R.sequence(R.of, cars)
[[]]

If I traverse a list instead of a dictionary it produces the correct cartesian product, but the results are (of course) lists instead of dictionaries.

R.sequence(R.of, [['yellow', 'red'], [2017], ['coup', 'sedan']])
[["yellow", 2017, "coup"], ["yellow", 2017, "sedan"], ["red", 2017, "coup"], ["red", 2017, "sedan"]]

Body:
I can think of two ways to do this, one involving sequence, and the other not.

This one uses your sequence(of) call above:

const convert = lift(map)(
  compose(zipObj, keys),
  compose(sequence(of), values)
)

const all_cars = convert(cars);

The other was built by my usual technique of keep changing the output with one transformation after another until I get to what I want:

const combine = pipe(
  toPairs,
  map(apply(useWith(map, [objOf, identity]))),
  reduce(xprod, [[]]),
  map(flatten),
  map(mergeAll)
)

const all_cars = combine(cars)

This might be made a little clearer by introducing a crossproduct across multiple lists:

const xproduct = reduce(pipe(xprod, map(unnest)), [[]])

const combine = pipe(
  toPairs,
  map(apply(useWith(map, [objOf, identity]))),
  xproduct,
  map(mergeAll)
)

The second version is what I came up with on first trying the problem.  Then when I looked to see what you'd tried, I got that first version.  That first version looks cleaner to me, although most of the individual steps in the second one are trivial.  But since there is one non-trivial step in there, the first one seems an overall winner.

You can see the first or <a href="http://ramdajs.com/repl/#?let%20cars%20%3D%20%7Bcolor%3A%20%5B%27yellow%27%2C%20%27red%27%5D%2C%20year%3A%20%5B2017%5D%2C%20model%3A%20%5B%27coup%27%2C%20%27sedan%27%5D%7D%0A%0Aconst%20xproduct%20%3D%20reduce%28pipe%28xprod%2C%20map%28unnest%29%29%2C%20%5B%5B%5D%5D%29%0A%0Aconst%20combine%20%3D%20pipe%28%0A%20%20toPairs%2C%0A%20%20map%28apply%28useWith%28map%2C%20%5BobjOf%2C%20identity%5D%29%29%29%2C%0A%20%20reduce%28xprod%2C%20%5B%5B%5D%5D%29%2C%0A%20%20map%28flatten%29%2C%0A%20%20map%28mergeAll%29%0A%29%0A%0Acombine%28cars%29%0A" rel="nofollow noreferrer">the second on the Ramda REPL.


问:
Group records by created_at in ActiveRecord
I'm trying to find how many records were created on a given day, to get something like this:

User uploaded 5 objects two days ago

User uploaded 12 objects 21 days ago

I've tried:

```<code>Flight.group("created_at::date")
</code>```

but get the error:

```<code>ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  column "flights.id" must appear in the GROUP BY clause or be used in an aggregate function
</code>```

but when I try adding the id either directly to the group field or by adding another .group I end up grouping on both the id and created_at, which obviously doesn't group anything since there would only be one instance of each match.

What am I missing here?

答:
If you're trying to count things then count them:

```<code>Flight.group('created_at::date').count         # PostgreSQL-only
Flight.group('date(created_at)').count         # PostgreSQL and AFAIK MySQL
Flight.group('cast(created_at as date)').count # Standard SQL
</code>```

That will give you a hash with dates as keys and counts as values. Otherwise, the database won't know which values from the rows in the group should be used to represent the group. If you add the count aggregate function then the ambiguity is gone and the database knows what you want it to do.

Body:
I'm trying to find how many records were created on a given day, to get something like this:

User uploaded 5 objects two days ago

User uploaded 12 objects 21 days ago

I've tried:

Flight.group("created_at::date")

but get the error:

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  column "flights.id" must appear in the GROUP BY clause or be used in an aggregate function

but when I try adding the id either directly to the group field or by adding another .group I end up grouping on both the id and created_at, which obviously doesn't group anything since there would only be one instance of each match.

What am I missing here?

Body:
If you're trying to count things then count them:

Flight.group('created_at::date').count         # PostgreSQL-only
Flight.group('date(created_at)').count         # PostgreSQL and AFAIK MySQL
Flight.group('cast(created_at as date)').count # Standard SQL

That will give you a hash with dates as keys and counts as values. Otherwise, the database won't know which values from the rows in the group should be used to represent the group. If you add the count aggregate function then the ambiguity is gone and the database knows what you want it to do.


问:
Importing csv file into J and using them as variable
I saved this data (20 vectors v)into csv file like this

```<code>v=:<"1 (? 20 2 $ 20)
makecsv v
v writecsv jpath'~temp/position.csv'
]vcsv =: freads jpath '~temp/position.csv'
fixcsv vcsv
</code>```

, and I could import the csv file by

```<code>readcsv jpath '~temp/position.csv'
</code>```

However, it doesn't give same result if I name it as

```<code>w=: readcsv jpath '~temp/position.csv'
diff=: ([{]) ,. ]

0 diff v
0 diff w
</code>```

Actually, 0 diff w gives a length error

Is there any other approach should I use to have same results from both v(original) and w(imported csv data)?

Thank you!

答:
I'm a J beginner so you may get a better answer later, but poking at it I think I have found something.

First, the tables/csv addon docs state that readcsv "Reads csv file into a boxed array," emphasis mine, while writecsv "Writes an array to a csv file." In other words, readcsv and writecsv are not symmetric operations. And the shapes of the values seem to confirm that:

```<code>   $ w
1 20
   $ v
20
</code>```

This is also why the diff works for v but not w. If you simply unbox the result, it seems to work better:

```<code>0 diff 0 { w
┌───┬─────┐
│1 3│1 3  │
├───┼─────┤
 ...
├───┼─────┤
│1 3│5 8  │
└───┴─────┘
</code>```

However, the shapes are still not exactly the same:

```<code>   $ > v
20 2
   $ > 0 { w
20 5
</code>```

I think this is because readcsv doesn't know that your values are numeric; you probably need to throw a ". in there somewhere to decode them.

Body:
I saved this data (20 vectors v)into csv file like this

v=:<"1 (? 20 2 $ 20)
makecsv v
v writecsv jpath'~temp/position.csv'
]vcsv =: freads jpath '~temp/position.csv'
fixcsv vcsv

, and I could import the csv file by

readcsv jpath '~temp/position.csv'

However, it doesn't give same result if I name it as

w=: readcsv jpath '~temp/position.csv'
diff=: ([{]) ,. ]

0 diff v
0 diff w

Actually, 0 diff w gives a length error

Is there any other approach should I use to have same results from both v(original) and w(imported csv data)?

Thank you!

Body:
I'm a J beginner so you may get a better answer later, but poking at it I think I have found something.

First, the tables/csv addon docs state that readcsv "Reads csv file into a boxed array," emphasis mine, while writecsv "Writes an array to a csv file." In other words, readcsv and writecsv are not symmetric operations. And the shapes of the values seem to confirm that:

   $ w
1 20
   $ v
20

This is also why the diff works for v but not w. If you simply unbox the result, it seems to work better:

0 diff 0 { w
┌───┬─────┐
│1 3│1 3  │
├───┼─────┤
 ...
├───┼─────┤
│1 3│5 8  │
└───┴─────┘

However, the shapes are still not exactly the same:

   $ > v
20 2
   $ > 0 { w
20 5

I think this is because readcsv doesn't know that your values are numeric; you probably need to throw a ". in there somewhere to decode them.


问:
Windows semaphores
I need to implement a program which uses a semaphore to limit the number of opened notepad windows to 10. I created a semaphore in  WM_INITDIALOG

```<code>    semafor = CreateSemaphore(0, 1, 10, "semaphore");
</code>```

and every time I click on button to open a new window, I open that semaphore. However it doesn't stop me from opening more than 10 windows.

Here is my code when I click on button in a dialog box to open a new window:

```<code>case WM_COMMAND:
    switch (LOWORD(wParam)) {
        case ID_OK:

            semafor = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, "semaphore");
            if (semafor == NULL) {
                printf("Eroare deschidere semafor empty: %d \n", GetLastError());
                ExitProcess(1);
            }

            BOOL b = CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi);

            process[++i] = GetCurrentProcess();

            if (b) {
                dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
                switch (dwWaitForChild) {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;
                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;
                case 0xFFFFFFFF:
                    printf("Eroare!\n");
                    break;
                }

                WaitForMultipleObjects(i, process, TRUE, INFINITE);

                iRasp = MessageBox(NULL, "Terminam procesul fiu?", "Atentie!", MB_YESNO);
                if (iRasp == IDYES) {
                    if (TerminateProcess(pi.hProcess, 2)) {

                        DWORD dwP;

                        GetExitCodeProcess(pi.hProcess, &dwP);
                        printf("Codul de terminare al procesului fiu: %d\n", dwP);
                        ReleaseSemaphore(semafor, 1, NULL);
                        CloseHandle(pi.hProcess);
                        printf("\nProcesul fiu a fost terminat cu succes\n");
                    }
                    else {
                        //tiparim mesajul de eroare
                        TCHAR buffer[80];
                        LPVOID lpMsgBuf;
                        DWORD dw = GetLastError();

                        FormatMessage(
                            FORMAT_MESSAGE_ALLOCATE_BUFFER |
                            FORMAT_MESSAGE_FROM_SYSTEM,
                            NULL,
                            dw,
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                            (LPTSTR)&lpMsgBuf,
                            0, NULL);

                        wsprintf(buffer, "TerminateProcess() a esuat cu eroarea %d: %s",
                            dw, lpMsgBuf);

                        MessageBox(NULL, buffer, "Eroare!", MB_OK);

                        LocalFree(lpMsgBuf);
                    }
                } // rasp YES

            }
            else
                printf("Eroare la crearea procesului fiu!\n");

            return TRUE;
        }
        break;
    }
    return FALSE;
}
</code>```

答:
You are misusing the semaphore.  Create the semaphore one time and reuse it, don't re-open it over and over.  But, more importantly, you have to wait on the semaphore, such as with WaitForSingleObject(), to decrement its counter, and then release it with ReleaseSeamphore() to increment its counter.  The state of the semaphore is signaled when its counter is greater than 0, and unsignaled when 0.

So, you need to create the semaphore with an initial count of 10 and then wait on it each time you want to create a new process.  If the wait fails, too many processes are already running.  Otherwise, if the wait succeeds, the counter has been decremented, so create the new process, and then increment the counter when the process ends.

However, that being said, your semaphore is completely useless in the context of the code you showed.  You want to use the semaphore to control the number of running instances of Notepad, but as soon as you launch 1 instance, you are attempting (incorrectly, I might add) to block your code until that instance exits.  So you will never be able to run more than 1 instance at a time, making the semaphore useless.  The fact that you are able to run more than 1 is likely due to a bug in your code (you are waiting on the wrong process handles!).  Don't use a blocking wait at all.  Let the system notify you when each spawned process ends.

A correct way to use a semaphore in your code would look something more like this instead:

```<code>const UINT WM_PROCESS_ENDED = WM_APP + 1;
const int MAX_PROCESSES = 10;

typedef struct procInfo
{
    HANDLE hProcess;
    HANDLE hWait;
} procInfo;

HANDLE semafor = NULL;
procInfo process[MAX_PROCESSES] = {};
int numProcesses = 0;
HWND hwndDialog;

...

VOID CALLBACK ProcessEnded(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    PostMessage(hwndDialog, WM_PROCESS_ENDED, 0, (LPARAM)lpParameter);
}

...

case WM_INITDIALOG:
{
    hwndDialog = hwnd;

    semafor = CreateSemaphore(0, MAX_PROCESSES, MAX_PROCESSES, NULL);
    if (semafor == NULL)
    {
        printf("Eroare deschidere semafor empty: %d \n", GetLastError());
        ExitProcess(1);
    }

    break;
}

case WM_DESTROY:
{
    for (int i = 0; i < numProcesses; ++i)
    {
        UnregisterWaitEx(process[i].hWait, INVALID_HANDLE_VALUE);
        TerminateProcess(process[i].hProcess, 2);
        CloseHandle(process[i].hProcess);
    }

    CloseHandle(semafor);
    semafor = NULL;

    hwndDialog = NULL;

    break;
}

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case ID_OK:
        {
            if (WaitForSingleObject(semafor, 0) != WAIT_OBJECT_0)
            {
                // too many instances running...
                break;
            }

            if (!CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi))
            {
                printf("Eroare la crearea procesului fiu!\n");
                ReleaseSemaphore(semafor, 1, NULL);
                break;
            }

            CloseHandle(pi.hThread);

            dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
            switch (dwWaitForChild)
            {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;

                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;

                case WAIT_FAILED:
                    printf("Eroare!\n");
                    break;
            }

            procInfo info;

            info.hProcess = pi.hProcess;
            if (!RegisterWaitForSingleObject(&info.hWait, pi.hProcess, &ProcessEnded, pi.hProcess, INFINITE, WT_EXECUTELONGFUNCTION | WT_EXECUTEONLYONCE))
            {
                TerminateProcess(pi.hProcess, 2);
                ReleaseSemaphore(semafor, 1, NULL);
                break;
            }

            process[numProcesses++] = info;
        }
    }

    break;
}

case WM_PROCESS_ENDED:
{
    HANDLE hProcess = (HANDLE)lParam;

    for (int i = 0; i < numProcesses; ++i)
    {
        if (process[i].hProcess == hProcess)
        {
            UnregisterWait(process[i].hWait);

            for (int j = i + 1; j < numProcesses; ++j)
                process[j-1] = process[j];

            --numProcesses;

            break;
        }
    }

    CloseHandle(hProcess);
    ReleaseSemaphore(semafor, 1, NULL);
}
</code>```

In which case, you can just get rid of the semaphore altogether since you already have your own counter:

```<code>const UINT WM_PROCESS_ENDED = WM_APP + 1;
const int MAX_PROCESSES = 10;

typedef struct procInfo
{
    HANDLE hProcess;
    HANDLE hWait;
} procInfo;

procInfo process[MAX_PROCESSES] = {};
int numProcesses = 0;
HWND hwndDialog;

...

VOID CALLBACK ProcessEnded(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    PostMessage(hwndDialog, WM_PROCESS_ENDED, 0, (LPARAM)lpParameter);
}

...

case WM_INITDIALOG:
{
    hwndDialog = hwnd;
    break;
}

case WM_DESTROY:
{
    for (int i = 0; i < numProcesses; ++i)
    {
        UnregisterWaitEx(wait[i], INVALID_HANDLE_VALUE);
        TerminateProcess(process[i], 2);
        CloseHandle(process[i]);
    }

    hwndDialog = NULL;

    break;
}

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case ID_OK:
        {
            if (numProcesses >= MAX_PROCESSES)
            {
                // too many instances running...
                break;
            }

            if (!CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi))
            {
                printf("Eroare la crearea procesului fiu!\n");
                break;
            }

            CloseHandle(pi.hThread);

            dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
            switch (dwWaitForChild)
            {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;

                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;

                case WAIT_FAILED:
                    printf("Eroare!\n");
                    break;
            }

            procInfo info;

            info.hProcess = pi.hProcess;
            if (!RegisterWaitForSingleObject(&info.hWait, pi.hProcess, &ProcessEnded, pi.hProcess, INFINITE, WT_EXECUTELONGFUNCTION | WT_EXECUTEONLYONCE))
            {
                TerminateProcess(pi.hProcess, 2);
                break;
            }

            process[numProcesses++] = info;
        }
    }

    break;
}

case WM_PROCESS_ENDED:
{
    HANDLE hProcess = (HANDLE)lParam;

    for (int i = 0; i < numProcesses; ++i)
    {
        if (process[i].hProcess == hProcess)
        {
            UnregisterWait(process[i].hWait);

            for (int j = i + 1; j < numProcesses; ++j)
                process[j-1] = process[j];

            --numProcesses;

            break;
        }
    }

    CloseHandle(hProcess);
}
</code>```

Title: Windows semaphores

Body:
I need to implement a program which uses a semaphore to limit the number of opened notepad windows to 10. I created a semaphore in  WM_INITDIALOG

    semafor = CreateSemaphore(0, 1, 10, "semaphore");

and every time I click on button to open a new window, I open that semaphore. However it doesn't stop me from opening more than 10 windows.

Here is my code when I click on button in a dialog box to open a new window:

case WM_COMMAND:
    switch (LOWORD(wParam)) {
        case ID_OK:

            semafor = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, "semaphore");
            if (semafor == NULL) {
                printf("Eroare deschidere semafor empty: %d \n", GetLastError());
                ExitProcess(1);
            }

            BOOL b = CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi);

            process[++i] = GetCurrentProcess();

            if (b) {
                dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
                switch (dwWaitForChild) {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;
                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;
                case 0xFFFFFFFF:
                    printf("Eroare!\n");
                    break;
                }

                WaitForMultipleObjects(i, process, TRUE, INFINITE);

                iRasp = MessageBox(NULL, "Terminam procesul fiu?", "Atentie!", MB_YESNO);
                if (iRasp == IDYES) {
                    if (TerminateProcess(pi.hProcess, 2)) {

                        DWORD dwP;

                        GetExitCodeProcess(pi.hProcess, &dwP);
                        printf("Codul de terminare al procesului fiu: %d\n", dwP);
                        ReleaseSemaphore(semafor, 1, NULL);
                        CloseHandle(pi.hProcess);
                        printf("\nProcesul fiu a fost terminat cu succes\n");
                    }
                    else {
                        //tiparim mesajul de eroare
                        TCHAR buffer[80];
                        LPVOID lpMsgBuf;
                        DWORD dw = GetLastError();

                        FormatMessage(
                            FORMAT_MESSAGE_ALLOCATE_BUFFER |
                            FORMAT_MESSAGE_FROM_SYSTEM,
                            NULL,
                            dw,
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                            (LPTSTR)&lpMsgBuf,
                            0, NULL);

                        wsprintf(buffer, "TerminateProcess() a esuat cu eroarea %d: %s",
                            dw, lpMsgBuf);

                        MessageBox(NULL, buffer, "Eroare!", MB_OK);

                        LocalFree(lpMsgBuf);
                    }
                } // rasp YES

            }
            else
                printf("Eroare la crearea procesului fiu!\n");

            return TRUE;
        }
        break;
    }
    return FALSE;
}

Body:
You are misusing the semaphore.  Create the semaphore one time and reuse it, don't re-open it over and over.  But, more importantly, you have to wait on the semaphore, such as with WaitForSingleObject(), to decrement its counter, and then release it with ReleaseSeamphore() to increment its counter.  The state of the semaphore is signaled when its counter is greater than 0, and unsignaled when 0.

So, you need to create the semaphore with an initial count of 10 and then wait on it each time you want to create a new process.  If the wait fails, too many processes are already running.  Otherwise, if the wait succeeds, the counter has been decremented, so create the new process, and then increment the counter when the process ends.

However, that being said, your semaphore is completely useless in the context of the code you showed.  You want to use the semaphore to control the number of running instances of Notepad, but as soon as you launch 1 instance, you are attempting (incorrectly, I might add) to block your code until that instance exits.  So you will never be able to run more than 1 instance at a time, making the semaphore useless.  The fact that you are able to run more than 1 is likely due to a bug in your code (you are waiting on the wrong process handles!).  Don't use a blocking wait at all.  Let the system notify you when each spawned process ends.

A correct way to use a semaphore in your code would look something more like this instead:

const UINT WM_PROCESS_ENDED = WM_APP + 1;
const int MAX_PROCESSES = 10;

typedef struct procInfo
{
    HANDLE hProcess;
    HANDLE hWait;
} procInfo;

HANDLE semafor = NULL;
procInfo process[MAX_PROCESSES] = {};
int numProcesses = 0;
HWND hwndDialog;

...

VOID CALLBACK ProcessEnded(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    PostMessage(hwndDialog, WM_PROCESS_ENDED, 0, (LPARAM)lpParameter);
}

...

case WM_INITDIALOG:
{
    hwndDialog = hwnd;

    semafor = CreateSemaphore(0, MAX_PROCESSES, MAX_PROCESSES, NULL);
    if (semafor == NULL)
    {
        printf("Eroare deschidere semafor empty: %d \n", GetLastError());
        ExitProcess(1);
    }

    break;
}

case WM_DESTROY:
{
    for (int i = 0; i < numProcesses; ++i)
    {
        UnregisterWaitEx(process[i].hWait, INVALID_HANDLE_VALUE);
        TerminateProcess(process[i].hProcess, 2);
        CloseHandle(process[i].hProcess);
    }

    CloseHandle(semafor);
    semafor = NULL;

    hwndDialog = NULL;

    break;
}

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case ID_OK:
        {
            if (WaitForSingleObject(semafor, 0) != WAIT_OBJECT_0)
            {
                // too many instances running...
                break;
            }

            if (!CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi))
            {
                printf("Eroare la crearea procesului fiu!\n");
                ReleaseSemaphore(semafor, 1, NULL);
                break;
            }

            CloseHandle(pi.hThread);

            dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
            switch (dwWaitForChild)
            {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;

                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;

                case WAIT_FAILED:
                    printf("Eroare!\n");
                    break;
            }

            procInfo info;

            info.hProcess = pi.hProcess;
            if (!RegisterWaitForSingleObject(&info.hWait, pi.hProcess, &ProcessEnded, pi.hProcess, INFINITE, WT_EXECUTELONGFUNCTION | WT_EXECUTEONLYONCE))
            {
                TerminateProcess(pi.hProcess, 2);
                ReleaseSemaphore(semafor, 1, NULL);
                break;
            }

            process[numProcesses++] = info;
        }
    }

    break;
}

case WM_PROCESS_ENDED:
{
    HANDLE hProcess = (HANDLE)lParam;

    for (int i = 0; i < numProcesses; ++i)
    {
        if (process[i].hProcess == hProcess)
        {
            UnregisterWait(process[i].hWait);

            for (int j = i + 1; j < numProcesses; ++j)
                process[j-1] = process[j];

            --numProcesses;

            break;
        }
    }

    CloseHandle(hProcess);
    ReleaseSemaphore(semafor, 1, NULL);
}

In which case, you can just get rid of the semaphore altogether since you already have your own counter:

const UINT WM_PROCESS_ENDED = WM_APP + 1;
const int MAX_PROCESSES = 10;

typedef struct procInfo
{
    HANDLE hProcess;
    HANDLE hWait;
} procInfo;

procInfo process[MAX_PROCESSES] = {};
int numProcesses = 0;
HWND hwndDialog;

...

VOID CALLBACK ProcessEnded(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    PostMessage(hwndDialog, WM_PROCESS_ENDED, 0, (LPARAM)lpParameter);
}

...

case WM_INITDIALOG:
{
    hwndDialog = hwnd;
    break;
}

case WM_DESTROY:
{
    for (int i = 0; i < numProcesses; ++i)
    {
        UnregisterWaitEx(wait[i], INVALID_HANDLE_VALUE);
        TerminateProcess(process[i], 2);
        CloseHandle(process[i]);
    }

    hwndDialog = NULL;

    break;
}

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case ID_OK:
        {
            if (numProcesses >= MAX_PROCESSES)
            {
                // too many instances running...
                break;
            }

            if (!CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi))
            {
                printf("Eroare la crearea procesului fiu!\n");
                break;
            }

            CloseHandle(pi.hThread);

            dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
            switch (dwWaitForChild)
            {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;

                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;

                case WAIT_FAILED:
                    printf("Eroare!\n");
                    break;
            }

            procInfo info;

            info.hProcess = pi.hProcess;
            if (!RegisterWaitForSingleObject(&info.hWait, pi.hProcess, &ProcessEnded, pi.hProcess, INFINITE, WT_EXECUTELONGFUNCTION | WT_EXECUTEONLYONCE))
            {
                TerminateProcess(pi.hProcess, 2);
                break;
            }

            process[numProcesses++] = info;
        }
    }

    break;
}

case WM_PROCESS_ENDED:
{
    HANDLE hProcess = (HANDLE)lParam;

    for (int i = 0; i < numProcesses; ++i)
    {
        if (process[i].hProcess == hProcess)
        {
            UnregisterWait(process[i].hWait);

            for (int j = i + 1; j < numProcesses; ++j)
                process[j-1] = process[j];

            --numProcesses;

            break;
        }
    }

    CloseHandle(hProcess);
}


问:
Python dict question. How to group similar strings?
```<code>for i in names:
    dict[i] = {'firstname': name[i]['firstname'],
               'lastname': name[i]['lastname']}
    print dict[0]['firstname'] # John
    print dict[0]['lastname'] # Doe

    # group similar lastnames, along with their firstnames
    # ...
return render_to_response('index.html', dict)
</code>```

I want to group names that end with similar last-names.
For example, the output should be:

```<code><html>
  <body>
    <h1> Doe </h1>
    <p> John, Jason, Peter </p>

    <h1> Avery </h1>
    <p> Kelly, Brittany </p>
  </body>
</html>
</code>```

The 'h1' tags are supposed to contain the last-names and the 'p' tags the first-names.

How should I do this?

答:
You mean something like this:

```<code>import collections

data = [
    {'firstname': 'John', 'lastname': 'Smith'},
    {'firstname': 'Samantha', 'lastname': 'Smith'},
    {'firstname': 'shawn', 'lastname': 'Spencer'},
]

new_data = collections.defaultdict(list)

for d in data:
    new_data[d['lastname']].append(d['firstname'])

print new_data
</code>```

Output :

```<code>defaultdict(<type 'list'>, {'Smith': ['John', 'Samantha'], 'Spencer': ['shawn']})
</code>```

in your template do:

```<code>{% for lastname, firstname in data.items %}
    <h1> {{ lastname }} </h1>
    <p> {{ firstname|join:", " }} </p>
{% endfor %}
</code>```

output:

```<code><h1> Smith </h1>
<p> John, Samantha </p>

<h1> Spencer </h1>
<p> shawn </p>
</code>```

Body:
for i in names:
    dict[i] = {'firstname': name[i]['firstname'],
               'lastname': name[i]['lastname']}
    print dict[0]['firstname'] # John
    print dict[0]['lastname'] # Doe

    # group similar lastnames, along with their firstnames
    # ...
return render_to_response('index.html', dict)

I want to group names that end with similar last-names.
For example, the output should be:

 Doe

 John, Jason, Peter

 Avery

 Kelly, Brittany

The 'h1' tags are supposed to contain the last-names and the 'p' tags the first-names.

How should I do this?

Body:
You mean something like this:

import collections

data = [
    {'firstname': 'John', 'lastname': 'Smith'},
    {'firstname': 'Samantha', 'lastname': 'Smith'},
    {'firstname': 'shawn', 'lastname': 'Spencer'},
]

new_data = collections.defaultdict(list)

for d in data:
    new_data[d['lastname']].append(d['firstname'])

print new_data

Output :

defaultdict(<type 'list'>, {'Smith': ['John', 'Samantha'], 'Spencer': ['shawn']})

in your template do:

{% for lastname, firstname in data.items %}
    <h1> {{ lastname }} </h1>
    <p> {{ firstname|join:", " }} </p>
{% endfor %}

output:

<h1> Smith </h1>
<p> John, Samantha </p>

<h1> Spencer </h1>
<p> shawn </p>


问:
A/B testing. Routing Clients in a gateway API
I am working on a new project that will be based on microservices. It's an internal app and only about 10 microservices. We will be using a gateway API for authentication and possibly some microservice aggregation. (Probably Netflix zuul with Spring Boot)

What I'm not clear on is how we do the routing for A/B testing and Canary testing. Lets assume I have 100 clients and we want to A/B test a new version of a microservice. The client app needs no changes, it's just internal changes to the function that the microservice provides.

I understand we would stand up a new microservice which is (say) v2. What I'm puzzled on is how do I direct (say) clients 1-10 to the new version. We need to be able to configure this centrally and not change anything on the client.

We know their mac addresses (as well as other identifying attributes) and can insert any kind of header we want to identify their messages.

So how would I direct these to v2 of the API for the A/B test or Canary deployment?

答:
To expound a bit on @Set's answer. You'll need to introduce some instrumentation code into your gateway API to make the decision about what downstream endpoint to call. If, and only if, the only component of your distributed backend that is concerned with this is the gateway API, the above solution is over-engineered: you can get by with just a library. But it's likely that you will soon discover that one or more of your other services needs to know about the experiment, in which case you DO need a standalone service.

Generally speaking, building a robust experimentation framework is a hard task though. You will quickly run into unexpected problems, e.g. experience stability (how to guarantee the same experience to return visitors) or how to change the allocation proportion (or perhaps completely turn off the new code) without the need to restart the host application. You ought to investigate the open source frameworks out there, or even commercial server side instrumentation. (We have one at Variant).


问:
How can I set the endpoint of a VPN Native Plugin in UWP?
I want to create a VPN app in UWP and I have the following code:

```<code>var profile = new VpnNativeProfile();

profile.AlwaysOn = true;
profile.NativeProtocolType = VpnNativeProtocolType.IpsecIkev2;
profile.ProfileName = "My Profile";
profile.RememberCredentials = true;
profile.RequireVpnClientAppUI = true;

var agent = new VpnManagementAgent();

agent.ConnectProfileWithPasswordCredentialAsync(profile, new PasswordCredential
{
      UserName = "test_username",
      Password = "test_password"
};
</code>```

My problem is: how do I set the endpoint (the VPN server IP address) for this VPN connection that I'm trying to create?

I don't see any property that specifies the endpoint of the VPN server that I want to connect to. Also, I haven't found any tutorial on this topic.

Any help will be greatly appreciated.

Thank you respectfully.

答:
You can specify the endpoint (Server address) this way</p>

```<code>profile.Servers.Add("ServerIpOrDomain");
</code>```

Body:
I want to create a VPN app in UWP and I have the following code:

var profile = new VpnNativeProfile();

profile.AlwaysOn = true;
profile.NativeProtocolType = VpnNativeProtocolType.IpsecIkev2;
profile.ProfileName = "My Profile";
profile.RememberCredentials = true;
profile.RequireVpnClientAppUI = true;

var agent = new VpnManagementAgent();

agent.ConnectProfileWithPasswordCredentialAsync(profile, new PasswordCredential
{
      UserName = "test_username",
      Password = "test_password"
};

My problem is: how do I set the endpoint (the VPN server IP address) for this VPN connection that I'm trying to create?

I don't see any property that specifies the endpoint of the VPN server that I want to connect to. Also, I haven't found any tutorial on this topic.

Any help will be greatly appreciated.

Thank you respectfully.

Body:
You can specify the endpoint (Server address) this way

profile.Servers.Add("ServerIpOrDomain");


问:
How to get random documents using spring mongorepository?
Lets assume the following structure:

A user class:

```<code>public class User {

@Id
String id;
String name;
//...

}
</code>```

The users repository:

```<code>public interface UserRepository extends MongoRepository<User, String> {

List<User> findByRandom(); // this method signature does not exist but would do what I intend to do

}
</code>```

A user controller:

```<code>@Component
public class UserController {

    private UserRepository users;

      @Autowired
      public UserController(
          UserRepository users) {
        this.users= users;
      }

public List<User> getRandomUsers() {
return(users.findByRandom()); // limit is missing here
}

        }
</code>```

How would one achieve to receive random documents out of a structure like this.
Having a field with a random value on the document would not be a desired solution, since the values should always be random (e.g. if I hit the random int value 4 and receive the x following items, those would always be the same). Having to query x times is also not prefered, since this would be too heavy load.
Can anyone help?

Thanks in advance,

Codehai

答:
Just use the $sample stage:

Via Spring-Data (from v2.0 onwards):

```<code>SampleOperation matchStage = Aggregation.sample(5);
Aggregation aggregation = Aggregation.newAggregation(sampleStage);
AggregationResults<OutType> output = mongoTemplate.aggregate(aggregation, "collectionName", OutType.class);
</code>```

Directly through the Java driver:

```<code>import static com.mongodb.client.model.Aggregates.*;
users.aggregate(Arrays.asList(sample(5)));
</code>```

Body:
Lets assume the following structure:

A user class:

public class User {

@Id
String id;
String name;
//...

}

The users repository:

public interface UserRepository extends MongoRepository<User, String> {

List<User> findByRandom(); // this method signature does not exist but would do what I intend to do

}

A user controller:

@Component
public class UserController {

    private UserRepository users;

      @Autowired
      public UserController(
          UserRepository users) {
        this.users= users;
      }

public List<User> getRandomUsers() {
return(users.findByRandom()); // limit is missing here
}

        }

How would one achieve to receive random documents out of a structure like this.
Having a field with a random value on the document would not be a desired solution, since the values should always be random (e.g. if I hit the random int value 4 and receive the x following items, those would always be the same). Having to query x times is also not prefered, since this would be too heavy load.
Can anyone help?

Thanks in advance,

Codehai

Body:
Just use the $sample stage:

Via Spring-Data (from v2.0 onwards):

SampleOperation matchStage = Aggregation.sample(5);
Aggregation aggregation = Aggregation.newAggregation(sampleStage);
AggregationResults<OutType> output = mongoTemplate.aggregate(aggregation, "collectionName", OutType.class);

Directly through the Java driver:

import static com.mongodb.client.model.Aggregates.*;
users.aggregate(Arrays.asList(sample(5)));


问:
Rails Production Server Google Font Not Loading
I have a production server running (digital ocean ruby on rails image [NGINX+UNICORN]), and everything is working except for google fonts. All other fonts that are local are located in the /public/fonts folder and are loaded as http://domain.com/fonts/font.eot. The problem is that the google fonts wont load
@import url(http://fonts.googleapis.com/css?family=Lato:300,400,900,300italic,400italic,900italic);

This makes my application looks really different and makes it sort of ugly. There is a similar question asked here: Heroku and Google Fonts but that solution does not work. I have also tried adding the  code instead of import but that also does not work. Finally I checked in the network tab of chrome and that does not work as well.

答:
For anyone else who comes across this problem, the solution that worked for me was to comment out the line config.assets.css_compressor = false in config/environments/production.rb

Hope this helps someone!