问:
Constrained matrices
I need to create all the possible matrix of dimension 5 (5x5), where all elements are integers from 0 to 100 and its sum is 100.

I'm not sure how to do it, or how to start... Any suggestion?

Despite I program in R, I'm looking for an idea of how to do it. Pseucode is fine.

My firs approach was getting all the permutations of 100 elements 25 times (one for each element in the matrix) and then take only those that sum 100. But that is 100^25 permutations... no way to do it in this by this approach.

I will thanks any idea and/or help!

答:
The OP is looking for all integer partitions of the number 100 of maximal length of 25.  The package partitions is equipped with a function exactly for this purpose called restrictedparts. E.g.:

```<code>library(partitions)
## all integer partitions of 10 of maximal length = 4
restrictedparts(10, 4)
[1,] 10 9 8 7 6 5 8 7 6 5 6 5 4 4 7 6 5 4 5 4 3 4 3
[2,]  0 1 2 3 4 5 1 2 3 4 2 3 4 3 1 2 3 4 2 3 3 2 3
[3,]  0 0 0 0 0 0 1 1 1 1 2 2 2 3 1 1 1 1 2 2 3 2 2
[4,]  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2
</code>```

Once all of the them have been generated, simply create a 5x5 matrix of each combinations (restrictedparts doesn't differentiate between 0 0 3 and 0 3 0). The only problem is that there are so many possible combinations (partitions::R(25, 100, TRUE) = 139620591) the function throws an error when you call restrictedparts(100, 25).

```<code>test <- restrictedparts(100, 25)
</code>```

Error in restrictedparts(100, 25) : NAs in foreign function call (arg 3)
      In addition: Warning message:
      In restrictedparts(100, 25) : NAs introduced by coercion to integer range

Since we can't generate them all via restrictedparts, we can generate them individually using firstrestrictedpart along with nextrestrictedpart like so:

```<code>funPartition <- function(n) {
    p <- firstrestrictedpart(100, 25)
    mat <- matrix(nrow = 25, ncol = n)
    mat[,1] <- p
    for (i in 2:n) {
        p <- nextrestrictedpart(p)
        mat[,i] <- p
    }
    mat
}

head(funPartition(5))
     [,1] [,2] [,3] [,4] [,5]
[1,]  100   99   98   97   96
[2,]    0    1    2    3    4
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    0    0    0    0    0
[6,]    0    0    0    0    0
</code>```

The only problem with this is that it isn't as efficient.

Enter RcppAlgos

There is a faster way using the package RcppAlgos(which I am the author of).

```<code>library(RcppAlgos)
combs <- comboGeneral(0:100,25,TRUE,"sum","==",100,rowCap=10^5)
matrixCombs <- lapply(1:nrow(combs), function(x) matrix(combs[x,], nrow = 5, ncol = 5))

matrixCombs[1:3]
[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    0    0    0    0  100

[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    1
[5,]    0    0    0    0   99

[[3]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    2
[5,]    0    0    0    0   98
</code>```

If you really want permutations, no problem, just call permuteGeneral:

```<code>perms <- permuteGeneral(0:100,25,TRUE,"sum","==",100,rowCap=10^5)
matrixPerms <- lapply(1:nrow(perms), function(x) matrix(perms[x,], nrow = 5, ncol = 5))

matrixPerms[1:3]
[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    0    0    0    0  100

[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0  100
[5,]    0    0    0    0    0

[[3]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0  100
[4,]    0    0    0    0    0
[5,]    0    0    0    0    0
</code>```

It is super fast as well. Let norm100Master be a wrapper of norm100 along with lapply(rep(5, runs), norm100).

```<code>funRcppAlgos <- function(myCap) {
    perms <- permuteGeneral(0:100,25,TRUE,"sum","==",100,rowCap=myCap)
    lapply(1:myCap, function(x) matrix(perms[x,], nrow = 5, ncol = 5))
}

runs <- 5000
microbenchmark(norm100Master(runs), funRcppAlgos(runs))
Unit: milliseconds
               expr       min        lq     mean    median        uq      max neval
norm100Master(runs) 50.930848 56.413103 65.00415 57.341665 64.242075 125.5940   100
 funRcppAlgos(runs)  8.711444  9.382808 13.05653  9.555321  9.912229 116.9166   100
</code>```

And comparing the sole generation of integer partitions with funPartition above (no conversion to matrices), we have:

```<code>microbenchmark(nextPs = funPartition(10^4),
               algos = comboGeneral(0:100,25,TRUE,"sum","==",100,10^4))
Unit: milliseconds
  expr        min        lq      mean    median        uq       max neval
nextPs 317.778757 334.35560 351.68058 343.81085 355.03575 521.13181   100
 algos   9.438661  10.12685  10.60887  10.37617  10.85003  13.99447   100
</code>```

And to test equality:

```<code>identical(t(apply(funPartition(10^4), 2, rev)),
          comboGeneral(0:100,25,TRUE,"sum","==",100,10^4))
[1] TRUE
</code>```

Title: Constrained matrices

Body:
The OP is looking for all integer partitions of the number 100 of maximal length of 25.  The package partitions is equipped with a function exactly for this purpose called restrictedparts. E.g.:

library(partitions)
## all integer partitions of 10 of maximal length = 4
restrictedparts(10, 4)
[1,] 10 9 8 7 6 5 8 7 6 5 6 5 4 4 7 6 5 4 5 4 3 4 3
[2,]  0 1 2 3 4 5 1 2 3 4 2 3 4 3 1 2 3 4 2 3 3 2 3
[3,]  0 0 0 0 0 0 1 1 1 1 2 2 2 3 1 1 1 1 2 2 3 2 2
[4,]  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2

Once all of the them have been generated, simply create a 5x5 matrix of each combinations (restrictedparts doesn't differentiate between 0 0 3 and 0 3 0). The only problem is that there are so many possible combinations (partitions::R(25, 100, TRUE) = 139620591) the function throws an error when you call restrictedparts(100, 25).

test <- restrictedparts(100, 25)

Error in restrictedparts(100, 25) : NAs in foreign function call (arg 3)
      In addition: Warning message:
      In restrictedparts(100, 25) : NAs introduced by coercion to integer range

Since we can't generate them all via restrictedparts, we can generate them individually using firstrestrictedpart along with nextrestrictedpart like so:

funPartition <- function(n) {
    p <- firstrestrictedpart(100, 25)
    mat <- matrix(nrow = 25, ncol = n)
    mat[,1] <- p
    for (i in 2:n) {
        p <- nextrestrictedpart(p)
        mat[,i] <- p
    }
    mat
}

head(funPartition(5))
     [,1] [,2] [,3] [,4] [,5]
[1,]  100   99   98   97   96
[2,]    0    1    2    3    4
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    0    0    0    0    0
[6,]    0    0    0    0    0

The only problem with this is that it isn't as efficient.

Enter RcppAlgos

There is a faster way using the package RcppAlgos(which I am the author of).

library(RcppAlgos)
combs <- comboGeneral(0:100,25,TRUE,"sum","==",100,rowCap=10^5)
matrixCombs <- lapply(1:nrow(combs), function(x) matrix(combs[x,], nrow = 5, ncol = 5))

matrixCombs[1:3]
[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    0    0    0    0  100

[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    1
[5,]    0    0    0    0   99

[[3]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    2
[5,]    0    0    0    0   98

If you really want permutations, no problem, just call permuteGeneral:

perms <- permuteGeneral(0:100,25,TRUE,"sum","==",100,rowCap=10^5)
matrixPerms <- lapply(1:nrow(perms), function(x) matrix(perms[x,], nrow = 5, ncol = 5))

matrixPerms[1:3]
[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0    0
[5,]    0    0    0    0  100

[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    0    0    0    0  100
[5,]    0    0    0    0    0

[[3]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0  100
[4,]    0    0    0    0    0
[5,]    0    0    0    0    0

It is super fast as well. Let norm100Master be a wrapper of norm100 along with lapply(rep(5, runs), norm100).

funRcppAlgos <- function(myCap) {
    perms <- permuteGeneral(0:100,25,TRUE,"sum","==",100,rowCap=myCap)
    lapply(1:myCap, function(x) matrix(perms[x,], nrow = 5, ncol = 5))
}

runs <- 5000
microbenchmark(norm100Master(runs), funRcppAlgos(runs))
Unit: milliseconds
               expr       min        lq     mean    median        uq      max neval
norm100Master(runs) 50.930848 56.413103 65.00415 57.341665 64.242075 125.5940   100
 funRcppAlgos(runs)  8.711444  9.382808 13.05653  9.555321  9.912229 116.9166   100

And comparing the sole generation of integer partitions with funPartition above (no conversion to matrices), we have:

microbenchmark(nextPs = funPartition(10^4),
               algos = comboGeneral(0:100,25,TRUE,"sum","==",100,10^4))
Unit: milliseconds
  expr        min        lq      mean    median        uq       max neval
nextPs 317.778757 334.35560 351.68058 343.81085 355.03575 521.13181   100
 algos   9.438661  10.12685  10.60887  10.37617  10.85003  13.99447   100

And to test equality:

identical(t(apply(funPartition(10^4), 2, rev)),
          comboGeneral(0:100,25,TRUE,"sum","==",100,10^4))
[1] TRUE


来源: stackexchange

问:
Jquery Table Body Not Displaying with SQL Data
I am trying to pull data from my SQL database and display it in a Jquery DataTable. I was able to do this with a Gridview but now want to change to a Jquery DataTable for more functionality. It seems like the data is being collected in my BindGrid() function but it will not actually display in the table on the webpage, the headers show but no information below them.

Here is a picture of my web form right now:

Also, here is all of my code as it stands now:

HTML:

```<code><div style="margin-top:30px;">
        <table class="table table-striped table-bordered" style="font-family: serif; border:1px;" id="netEventTable" clientIdMode="static">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Username</th>
                    <th>Type</th>
                    <th>Subject Line</th>
                    <th>Start Time</th>
                    <th>Estimated Time of Resolution</th>
                </tr>
            </thead>
            <tbody id="netEventTableBody" runat="server">

            </tbody>
        </table>
    </div>
</code>```

JQUERY:

```<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js" type="text/javascript"></script>
<link href="" rel="stylesheet" />
<script type="text/javascript">
    $(document).ready(function () {
        $('#netEventTable').dataTable({
            "bLengthChange": true,
            "paging": true,
            "sPaginationType": "full_numbers",
            "jQueryUI": true,
        });
    });
</script>
</code>```

C# (CodeBehind):

```<code> protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            this.BindGrid();
        }
    }

    private void BindGrid()
    {
        string strSQLConn = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;
        try
        {
            // Jquery DataTable
            SqlConnection con = new SqlConnection(strSQLConn);
            con.Open();
            SqlCommand cmd = new SqlCommand("getNetEvents", con);
            SqlDataReader user = cmd.ExecuteReader();
            String UnreadText = "";
            Int32 i = 0;
            while (user.Read())
            {
                UnreadText += "<tr>";
                UnreadText += "<td class=\'center'>" + user["ID"] + "</td>";
                UnreadText += "<td class=\'center'>" + user["Name"] + "</td>";
                UnreadText += "<td class=\'center'>" + user["Type"] + "</td>";
                UnreadText += "<td class=\'center'>" + user["SubjectLine"] + "</td>";
                UnreadText += "<td class=\'center'>" + user["StartTime"] + "</td>";
                UnreadText += "<td class=\'center'>" + user["EndTime"] + "</td>";
                UnreadText += "</tr>";
                i++;
            }
            con.Close();

        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR: " + ex.ToString());
            Helpers.ApplicationLogHelper.createApplicationLogError("ERROR", ex.ToString());
            return;
        }
    }
</code>```

How can I get the data from my SQL server to display in the Jquery DataTable?

答:
I think you're missing this part,

```<code>"ajax": {
        url: 'some url',
        type: "GET",
        error: function (data) {
            //catch error
        }
    }
</code>```

because you are just initializing the jquery datatable so it won't do anything at all.

ContentLicense: CC BY-SA 3.0

Body:
I am trying to pull data from my SQL database and display it in a Jquery DataTable. I was able to do this with a Gridview but now want to change to a Jquery DataTable for more functionality. It seems like the data is being collected in my BindGrid() function but it will not actually display in the table on the webpage, the headers show but no information below them.

Here is a picture of my web form right now:

Also, here is all of my code as it stands now:

HTML:

                    ID
                    Username
                    Type
                    Subject Line
                    Start Time
                    Estimated Time of Resolution

JQUERY:

<link href="" rel="stylesheet" />

C# (CodeBehind):

 protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            this.BindGrid();
        }
    }

    private void BindGrid()
    {
        string strSQLConn = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;
        try
        {
            // Jquery DataTable
            SqlConnection con = new SqlConnection(strSQLConn);
            con.Open();
            SqlCommand cmd = new SqlCommand("getNetEvents", con);
            SqlDataReader user = cmd.ExecuteReader();
            String UnreadText = "";
            Int32 i = 0;
            while (user.Read())
            {
                UnreadText += "
";
                UnreadText += "" + user["ID"] + "	";
                UnreadText += "" + user["Name"] + "	";
                UnreadText += "" + user["Type"] + "	";
                UnreadText += "" + user["SubjectLine"] + "	";
                UnreadText += "" + user["StartTime"] + "	";
                UnreadText += "" + user["EndTime"] + "	";
                UnreadText += "
";
                i++;
            }
            con.Close();

        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR: " + ex.ToString());
            Helpers.ApplicationLogHelper.createApplicationLogError("ERROR", ex.ToString());
            return;
        }
    }

How can I get the data from my SQL server to display in the Jquery DataTable?

Body:
I think you're missing this part,

"ajax": {
        url: 'some url',
        type: "GET",
        error: function (data) {
            //catch error
        }
    }

because you are just initializing the jquery datatable so it won't do anything at all.


问:
Increasing network IO on EC2
I'm executing a Spark job on EMR. The job is currently being bottlenecked by network (reading data from S3). Looking at metrics in Ganglia, I get a straight line at around 600 MBPs. I'm using i2.8x large instance type which is suppose to give 10Gbps i.e. ~ 1280MBPs. I have verified that enhanced networking is turned on and VirtualizationType is hvm, Am I missing something? Is there any other way to increase network throughput? </p>

答:
The S3->EC2 bandwidth is actually rate limited at 5Gbps (625MB/s) on the largest instance types of each EC2 family, even on instances with Enhanced Networking and a 20Gbps network interface. This has been confirmed by the S3 team, and it matches what I observed in my experiments. Smaller instances get rate limited at lower rates.

S3's time-to-first-byte is about 80-100ms, and after the first byte it is able to deliver data to a single thread at 85MB/s, in theory. However, we've only observed about 60MB/s per thread on average (IIRC). S3 confirmed that this is expected, and slightly higher than what their customers observe. We used an HTTP client that kept connections alive to the S3 endpoint. The main reason small objects yield low throughput is the high time-to-first-byte.

The following is the max bandwidth we've observed (in MB/s) when downloading from S3 using various EC2 instances:

```<code>Instance  MB/s
C3.2XL    114
C3.4XL    245
C3.8XL    600
C4.L      67
C4.XL     101
C4.2XL    266
C4.4XL    580
C4.8XL    600
I2.8XL    600
M3.XL     117
M3.2XL    117
M4.XL     95
M4.10XL   585
X1.32XL   612
</code>```

We've done the above test with 32MB objects and a thread count between 10-16.

Also,

Network performance quoted on ec2 instances matrix are benchmarked as described here. This is network bandwidth between Amazon EC2 Linux instances in the same VPC. The one we are observing between s3 and ec2 instances is not what they have promised.

EC2 Instance Network performance appears to be categorized as:

Low

Moderate

High

10 Gigabit

20 Gigabit

Determining Network bandwidth on an instance designated Low, Moderate, or High appears to be done on a case-by-case basis.

C3, C4, R3, I2, M4 and D2 instances use Intel® 82599g Virtual Function Interface and provide Enhanced Networking with 10 Gigabit interfaces in the largest instance size.

10 and 20 Gigabit interfaces are only able to achieve that speed when communicating within a common Placement Group, typically in support of HPC. Network traffic outside a placement group is has a max limit of 5 Gbps.

Summary:  Network bandwidth mentioned is between two instances not between s3 and ec2.Even between two instances when they are in same placement group + have support of HPC we can achieve something around 10/20 Gigabit.

Title: Increasing network IO on EC2

Body:
The S3->EC2 bandwidth is actually rate limited at 5Gbps (625MB/s) on the largest instance types of each EC2 family, even on instances with Enhanced Networking and a 20Gbps network interface. This has been confirmed by the S3 team, and it matches what I observed in my experiments. Smaller instances get rate limited at lower rates.

S3's time-to-first-byte is about 80-100ms, and after the first byte it is able to deliver data to a single thread at 85MB/s, in theory. However, we've only observed about 60MB/s per thread on average (IIRC). S3 confirmed that this is expected, and slightly higher than what their customers observe. We used an HTTP client that kept connections alive to the S3 endpoint. The main reason small objects yield low throughput is the high time-to-first-byte.

The following is the max bandwidth we've observed (in MB/s) when downloading from S3 using various EC2 instances:

Instance  MB/s
C3.2XL    114
C3.4XL    245
C3.8XL    600
C4.L      67
C4.XL     101
C4.2XL    266
C4.4XL    580
C4.8XL    600
I2.8XL    600
M3.XL     117
M3.2XL    117
M4.XL     95
M4.10XL   585
X1.32XL   612

We've done the above test with 32MB objects and a thread count between 10-16.

Also,

Network performance quoted on ec2 instances matrix are benchmarked as described here. This is network bandwidth between Amazon EC2 Linux instances in the same VPC. The one we are observing between s3 and ec2 instances is not what they have promised.

EC2 Instance Network performance appears to be categorized as:

Low

Moderate

High

10 Gigabit

20 Gigabit

Determining Network bandwidth on an instance designated Low, Moderate, or High appears to be done on a case-by-case basis.

C3, C4, R3, I2, M4 and D2 instances use Intel® 82599g Virtual Function Interface and provide Enhanced Networking with 10 Gigabit interfaces in the largest instance size.

10 and 20 Gigabit interfaces are only able to achieve that speed when communicating within a common Placement Group, typically in support of HPC. Network traffic outside a placement group is has a max limit of 5 Gbps.

Summary:  Network bandwidth mentioned is between two instances not between s3 and ec2.Even between two instances when they are in same placement group + have support of HPC we can achieve something around 10/20 Gigabit.


问:
Distributed and Parallel Computer Unisex Bathroom Solution in Python
Suppose you are at a party in the Public Calamity republic that has only
a bathroom with n boxes, where box is a compartment with a toilet. The rule of
Republic says that the bathroom can be used by both men and women, but not to the Same time. Make a concurrent monitor-based algorithm that controls the use of this WC.

Entry into the bathroom is carried out by the procedure in the bathroom. After entering the bathroom successfully, people should call the procedureBoxBox, to use a box If all the boxes are in use then they should wait in a queue, there is enough space in the bathroom. After using a box, each person calls the procedure
liberaBox so that others can use it.

The republic still imposes that the use of the bathroom should be fair as follows. Suppose that at one point the bathroom is in use by
same sex (some using boxes and others waiting), and the first person of the opposite sex arrives, called P.
So:

• P only enters the bathroom after the exit of all x individuals from the bathroom;

• As long as P is expecting, if other same-sex individuals arrive, they will use the bathroom simultaneously with P;

• While P is waiting, if individuals of the opposite sex come to use the bathroom, they enter the bathroom after P (and their same-sex mates, if any) get out of the bathroom;

• While P (and same-sex mates) are using the bathroom, if same sex as P, they will expect all people of the opposite sex from P to leave before you start using the bathroom.

Each person of both sexes should be a separate process. There is no person controlling access to the bathroom, but all people know the rules of using the bathroom and obey them (no one sticks the line!).

Three problems should be addressed:

Problem 1:
Consider that the bathroom has only one box (n = 1).
In all, 50 people will use the bathroom with a random number generator setting the sex (with equal probability).

Use a random number generator so that the time between people arriving is
between 1 and 7 seconds.~

Each person uses the bathroom for exactly 5 seconds.
Use threads and monitors for synchronization. You can also use shared memory.
At the end of the program run a report containing:

• Number of people of each sex;

• Average waiting time to use the bathroom for each sex;

• Box occupancy rate (time in use / total time).

Problem 2:
Consider now that the bathroom has 3 boxes (n = 3) and that the total number of people is 150.

Problem 3:
Consider now that the bathroom has 5 boxes (n = 5) and that the total number of people is 250

```<code>import threading
import random
from time import sleep

# constants
MALE = 1
FEMALE = 0

print("\n***************************************************************\nBem vindo ao banheiro unisex da Rep. Calamidade Pública\n***************************************************************\n\nDigite 1 para Problema 1\nDigite 2 para Problema 2\nDigite 3 para Problema 3\n\n***************************************************************")
print("")
menu = input("Seleção: ")

# global variables
queue = list()               # to maintain queue outside bathroom
countPerson = 1                  # provides id for each person
countMale = 0
countFemale = 0
PeopleInBathroom = 0
GenderUsingBathroom = 0

if menu == '1':
    numBox = 1
elif menu == '2':
    numBox = 3
elif menu == '3':
    numBox = 5

# semaphores
sem_bathroom = threading.Semaphore(value=numBox)
sem_queue = threading.Semaphore()
sem_mutex = threading.Semaphore()

#generates people who need to use bathroom at random times
def GeneratePeople():
    global queue
    global countMale
    global countFemale
    global countPerson

    if menu == '1':
        sem_queue.acquire()
        for i in range(0, 50):
            if random.randint(0,1) == MALE:
                queue.insert(0,[MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.insert(0,[FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '2':
        sem_queue.acquire()
        for i in range(0, 150):
            if random.randint(0,1) == MALE:
                queue.insert(0,[MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.insert(0,[FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '3':
        sem_queue.acquire()
        for i in range(0, 250):
            if random.randint(0,1) == MALE:
                queue.insert(0,[MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.insert(0,[FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
# end of GeneratePeople

# function to send people into bathroom for queue
def entraBanheiro():
    global queue
    global GenderUsingBathroom
    global PeopleInBathroom

    while 1:
        sem_queue.acquire()
        if len(queue)>0:
            p = queue.pop()
            sem_queue.release()
            sem_mutex.acquire()  # for GenderUsingBathroom
            if GenderUsingBathroom == p[0] :    # if same gender, go in
                sem_mutex.release()
                sem_bathroom.acquire()
                t = threading.Thread(target=liberaBox,args=(p,))
                t.start()
            else:                               # if different gender, wait till all others come out
                print ("Esperando por outra pessoa do mesmo sexo")
                while PeopleInBathroom > 0:
                    sem_mutex.release()
                    sleep(1)
                    sem_mutex.acquire()
                sem_mutex.release()
                sem_bathroom.acquire()
                GenderUsingBathroom = p[0]
                t1 = threading.Thread(target=liberaBox,args=(p,))
                t1.start()
        else:
            sem_queue.release()
# end of entraBanheiro

def liberaBox(person):             # monitors the usage of bathroom for each person
    global PeopleInBathroom
    flag = 1
    sem_mutex.acquire()
    if person[0] == FEMALE:
        print("Uma mulher acabou de entrar no banheiro")
        flag = 0
    else:
        print ("Um homem acabou de entrar no banheiro")
    PeopleInBathroom += 1   # enters bathroom
    sem_mutex.release()
    sleep(5)    # spend some time in bathroom
    sem_mutex.acquire()
    PeopleInBathroom -= 1   #leave bathroom
    print ("Pessoa #" , person[1]," acabou de sair do banheiro")
    sem_mutex.release()
    sem_bathroom.release()
# end of liberaBox

if __name__ == "__main__":

    t1 = threading.Thread(target=GeneratePeople)
    t1.start()
    t2 = threading.Thread(target=entraBanheiro)
    t2.start()

    #print("\n***************************************************************\nEstatisticas\n\n***************************************************************\n")
    #print("Homens: ", countMale)
    #print("Mulheres: ", countFemale)
</code>```

The problem is the code generates all people first then they enter in WC. How to implement this for both thread run at same time?

答:
```<code>def GeneratePeople():
    global queue
    global countMale
    global countFemale
    global countPerson

    if menu == '1':
        sem_queue.acquire()
        for i in range(0, 50):
            if random.randint(0,1) == MALE:
                queue.put([MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.put([FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '2':
        sem_queue.acquire()
        for i in range(0, 150):
            if random.randint(0,1) == MALE:
                queue.put([MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.put([FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '3':
        sem_queue.acquire()
        for i in range(0, 250):
            if random.randint(0,1) == MALE:
                queue.put([MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.put([FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()

# end of GeneratePeople

# function to send people into bathroom for queue
def entraBanheiro():
    global queue
    global GenderUsingBathroom
    global PeopleInBathroom

    while 1:
        sem_queue.acquire()
        if queue.qsize() > 0:
            p = queue.get()
            sem_queue.release()
            sem_mutex.acquire()  # for GenderUsingBathroom
            if GenderUsingBathroom == p[0] :    # if same gender, go in
                sem_mutex.release()
                sem_bathroom.acquire()
                t1 = threading.Thread(target=liberaBox,args=(p,))
                t1.start()
            else:                               # if different gender, wait till all others come out
                print ("Esperando por outra pessoa do mesmo sexo")
                while PeopleInBathroom > 0:
                    sem_mutex.release()
                    #sleep(1)
                    sem_mutex.acquire()
                sem_mutex.release()
                sem_bathroom.acquire()
                GenderUsingBathroom = p[0]
                t2 = threading.Thread(target=liberaBox,args=(p,))
                t2.start()
        else:
            sem_queue.release()
# end of entraBanheiro

def liberaBox(person):             # monitors the usage of bathroom for each person
    global PeopleInBathroom
    flag = 1
    sem_mutex.acquire()
    if person[0] == FEMALE:
        print("Uma mulher acabou de entrar no banheiro")
        flag = 0
    else:
        print ("Um homem acabou de entrar no banheiro")
    PeopleInBathroom += 1   # enters bathroom
    sem_mutex.release()
    sleep(5)    # spend some time in bathroom
    sem_mutex.acquire()
    PeopleInBathroom -= 1   #leave bathroom
    print ("Pessoa #" , person[1]," acabou de sair do banheiro")
    sem_mutex.release()
    sem_bathroom.release()
# end of liberaBox

if __name__ == "__main__":

      t3 = Process(target=GeneratePeople).start()
      t4 = Process(target=entraBanheiro).start()
</code>```

But now my question is how to implement "Average waiting time to use the bathroom for each sex" and "Box occupancy rate (time in use / total time)"?

Body:
Suppose you are at a party in the Public Calamity republic that has only
a bathroom with n boxes, where box is a compartment with a toilet. The rule of
Republic says that the bathroom can be used by both men and women, but not to the Same time. Make a concurrent monitor-based algorithm that controls the use of this WC.

Entry into the bathroom is carried out by the procedure in the bathroom. After entering the bathroom successfully, people should call the procedureBoxBox, to use a box If all the boxes are in use then they should wait in a queue, there is enough space in the bathroom. After using a box, each person calls the procedure
liberaBox so that others can use it.

The republic still imposes that the use of the bathroom should be fair as follows. Suppose that at one point the bathroom is in use by
same sex (some using boxes and others waiting), and the first person of the opposite sex arrives, called P.
So:

• P only enters the bathroom after the exit of all x individuals from the bathroom;

• As long as P is expecting, if other same-sex individuals arrive, they will use the bathroom simultaneously with P;

• While P is waiting, if individuals of the opposite sex come to use the bathroom, they enter the bathroom after P (and their same-sex mates, if any) get out of the bathroom;

• While P (and same-sex mates) are using the bathroom, if same sex as P, they will expect all people of the opposite sex from P to leave before you start using the bathroom.

Each person of both sexes should be a separate process. There is no person controlling access to the bathroom, but all people know the rules of using the bathroom and obey them (no one sticks the line!).

Three problems should be addressed:

Problem 1:
Consider that the bathroom has only one box (n = 1).
In all, 50 people will use the bathroom with a random number generator setting the sex (with equal probability).

Use a random number generator so that the time between people arriving is
between 1 and 7 seconds.~

Each person uses the bathroom for exactly 5 seconds.
Use threads and monitors for synchronization. You can also use shared memory.
At the end of the program run a report containing:

• Number of people of each sex;

• Average waiting time to use the bathroom for each sex;

• Box occupancy rate (time in use / total time).

Problem 2:
Consider now that the bathroom has 3 boxes (n = 3) and that the total number of people is 150.

Problem 3:
Consider now that the bathroom has 5 boxes (n = 5) and that the total number of people is 250

import threading
import random
from time import sleep

# constants
MALE = 1
FEMALE = 0

print("\n***************************************************************\nBem vindo ao banheiro unisex da Rep. Calamidade Pública\n***************************************************************\n\nDigite 1 para Problema 1\nDigite 2 para Problema 2\nDigite 3 para Problema 3\n\n***************************************************************")
print("")
menu = input("Seleção: ")

# global variables
queue = list()               # to maintain queue outside bathroom
countPerson = 1                  # provides id for each person
countMale = 0
countFemale = 0
PeopleInBathroom = 0
GenderUsingBathroom = 0

if menu == '1':
    numBox = 1
elif menu == '2':
    numBox = 3
elif menu == '3':
    numBox = 5

# semaphores
sem_bathroom = threading.Semaphore(value=numBox)
sem_queue = threading.Semaphore()
sem_mutex = threading.Semaphore()

#generates people who need to use bathroom at random times
def GeneratePeople():
    global queue
    global countMale
    global countFemale
    global countPerson

    if menu == '1':
        sem_queue.acquire()
        for i in range(0, 50):
            if random.randint(0,1) == MALE:
                queue.insert(0,[MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.insert(0,[FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '2':
        sem_queue.acquire()
        for i in range(0, 150):
            if random.randint(0,1) == MALE:
                queue.insert(0,[MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.insert(0,[FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '3':
        sem_queue.acquire()
        for i in range(0, 250):
            if random.randint(0,1) == MALE:
                queue.insert(0,[MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.insert(0,[FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
# end of GeneratePeople

# function to send people into bathroom for queue
def entraBanheiro():
    global queue
    global GenderUsingBathroom
    global PeopleInBathroom

    while 1:
        sem_queue.acquire()
        if len(queue)>0:
            p = queue.pop()
            sem_queue.release()
            sem_mutex.acquire()  # for GenderUsingBathroom
            if GenderUsingBathroom == p[0] :    # if same gender, go in
                sem_mutex.release()
                sem_bathroom.acquire()
                t = threading.Thread(target=liberaBox,args=(p,))
                t.start()
            else:                               # if different gender, wait till all others come out
                print ("Esperando por outra pessoa do mesmo sexo")
                while PeopleInBathroom > 0:
                    sem_mutex.release()
                    sleep(1)
                    sem_mutex.acquire()
                sem_mutex.release()
                sem_bathroom.acquire()
                GenderUsingBathroom = p[0]
                t1 = threading.Thread(target=liberaBox,args=(p,))
                t1.start()
        else:
            sem_queue.release()
# end of entraBanheiro

def liberaBox(person):             # monitors the usage of bathroom for each person
    global PeopleInBathroom
    flag = 1
    sem_mutex.acquire()
    if person[0] == FEMALE:
        print("Uma mulher acabou de entrar no banheiro")
        flag = 0
    else:
        print ("Um homem acabou de entrar no banheiro")
    PeopleInBathroom += 1   # enters bathroom
    sem_mutex.release()
    sleep(5)    # spend some time in bathroom
    sem_mutex.acquire()
    PeopleInBathroom -= 1   #leave bathroom
    print ("Pessoa #" , person[1]," acabou de sair do banheiro")
    sem_mutex.release()
    sem_bathroom.release()
# end of liberaBox

if __name__ == "__main__":

    t1 = threading.Thread(target=GeneratePeople)
    t1.start()
    t2 = threading.Thread(target=entraBanheiro)
    t2.start()

    #print("\n***************************************************************\nEstatisticas\n\n***************************************************************\n")
    #print("Homens: ", countMale)
    #print("Mulheres: ", countFemale)

The problem is the code generates all people first then they enter in WC. How to implement this for both thread run at same time?

Body:
def GeneratePeople():
    global queue
    global countMale
    global countFemale
    global countPerson

    if menu == '1':
        sem_queue.acquire()
        for i in range(0, 50):
            if random.randint(0,1) == MALE:
                queue.put([MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.put([FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '2':
        sem_queue.acquire()
        for i in range(0, 150):
            if random.randint(0,1) == MALE:
                queue.put([MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.put([FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()
    elif menu == '3':
        sem_queue.acquire()
        for i in range(0, 250):
            if random.randint(0,1) == MALE:
                queue.put([MALE,countPerson]);
                countPerson += 1
                countMale += 1
                print ("Um homem chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
            else:
                queue.put([FEMALE,countPerson]);
                countPerson += 1
                countFemale += 1
                print ("Uma mulher chegou na fila na posição #", countPerson-1)
                sleep(random.randint(1, 7))
        sem_queue.release()

# end of GeneratePeople

# function to send people into bathroom for queue
def entraBanheiro():
    global queue
    global GenderUsingBathroom
    global PeopleInBathroom

    while 1:
        sem_queue.acquire()
        if queue.qsize() > 0:
            p = queue.get()
            sem_queue.release()
            sem_mutex.acquire()  # for GenderUsingBathroom
            if GenderUsingBathroom == p[0] :    # if same gender, go in
                sem_mutex.release()
                sem_bathroom.acquire()
                t1 = threading.Thread(target=liberaBox,args=(p,))
                t1.start()
            else:                               # if different gender, wait till all others come out
                print ("Esperando por outra pessoa do mesmo sexo")
                while PeopleInBathroom > 0:
                    sem_mutex.release()
                    #sleep(1)
                    sem_mutex.acquire()
                sem_mutex.release()
                sem_bathroom.acquire()
                GenderUsingBathroom = p[0]
                t2 = threading.Thread(target=liberaBox,args=(p,))
                t2.start()
        else:
            sem_queue.release()
# end of entraBanheiro

def liberaBox(person):             # monitors the usage of bathroom for each person
    global PeopleInBathroom
    flag = 1
    sem_mutex.acquire()
    if person[0] == FEMALE:
        print("Uma mulher acabou de entrar no banheiro")
        flag = 0
    else:
        print ("Um homem acabou de entrar no banheiro")
    PeopleInBathroom += 1   # enters bathroom
    sem_mutex.release()
    sleep(5)    # spend some time in bathroom
    sem_mutex.acquire()
    PeopleInBathroom -= 1   #leave bathroom
    print ("Pessoa #" , person[1]," acabou de sair do banheiro")
    sem_mutex.release()
    sem_bathroom.release()
# end of liberaBox

if __name__ == "__main__":

      t3 = Process(target=GeneratePeople).start()
      t4 = Process(target=entraBanheiro).start()

But now my question is how to implement "Average waiting time to use the bathroom for each sex" and "Box occupancy rate (time in use / total time)"?


问:
Can't insert values using pl\pgSQL procedure
I have a problem with my procedure. We have 2 tables : companies and typeofcompanies.  Companies have 3 columns ("companyid","companyname","typeofcompany") , typeofcompanies have 2 columns ("typeofcompanyId", "typeofcompany");

This is my code for insert values into companies:

```<code> CREATE OR REPLACE FUNCTION insert_to_companies(c_name VARCHAR(255),toc INTEGER)
      RETURNS VOID AS $$
          DECLARE i integer;
           BEGIN
          FOR i IN SELECT "typeofcompanyId" FROM typeofcompanies LOOP
            IF toc = i THEN insert into public.companies(companyname, typeofcompany) VALUES (c_name,toc);
              END IF;
          END LOOP;
          IF(SELECT companyname FROM companies WHERE companyname = c_name) = NULL THEN insert into public.typeofcompanies(typeofcompany) VALUES (toc);
                                                                             INSERT into public.companies(companyname,typeofcompany) VALUES (c_name,toc);
          END IF;
          END;
    $$ LANGUAGE plpgsql VOLATILE;
</code>```

So if we haven't typeofcompany we should create it. But when i SELECT insert_to_companies("1",5);  i take  ERROR: column "1" does not exist.   So i think it's very easier problem, but i spent more than 3 hour and can't find problem. Please, i need help....

code for creating table with liquibase

companies:

```<code><databaseChangeLog xmlns = "http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
    <changeSet id="1" author="tiurinvalery@gmail.com" runOnChange="true" >
        <createTable tableName ="companies">
            <column autoIncrement = "true" name = "companyid" type ="BIGINT">
                <constraints primaryKey ="true"></constraints>
            </column>
            <column name="companyname" type="VARCHAR(255)">
            </column>
            <column name="typeofcompany" type="INTEGER">
            </column>
        </createTable>
    </changeSet>
 </databaseChangeLog>
</code>```

For type of companies:

```<code><databaseChangeLog xmlns = "http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd"  >
    <changeSet id="5" author="tiurinvalery@gmail.com" runOnChange="true" >
        <createTable tableName ="typeofcompanies">
            <column autoIncrement = "true" name = "typeofcompanyId" type ="BIGINT">
                <constraints nullable="false" primaryKey="true"></constraints>
            </column>
            <column name = "typeofcompany" type="VARCHAR(255)">
                <constraints nullable="false"></constraints>
            </column>
        </createTable>
    </changeSet>
</databaseChangeLog>
</code>```

答:
Table definitions could look like this:

```<code>CREATE TABLE company_type (
   company_type_id serial PRIMARY KEY
 , company_type    text UNIQUE NOT NULL
);

CREATE TABLE company (
   company_id      serial PRIMARY KEY
 , company         text NOT NULL
 , company_type_id int REFERENCES company_type
);
</code>```

I made a couple of changes:

Not using double-quoted CaMeL-case names. Avoid that, if you can.

Are PostgreSQL column names case-sensitive?

Using integer instead of bigint for PK IDs. I seriously doubt you'll exhaust the key space with company types in this century ...

Using just text. varchar(255) typically is a misunderstanding in Postgres.

The best function (or just query) heavily depends on your use case. DB load, concurrency, exact requirements. If concurrent writes are possible, I suggest this to avoid race conditions:

```<code>CREATE OR REPLACE FUNCTION f_insert_to_companies(_c_name text, _toc text)
  RETURNS void AS
$func$
BEGIN
LOOP
   INSERT INTO company(company, company_type_id)
   SELECT _c_name, t.company_type_id
   FROM   company_type t
   WHERE  company_type = _toc;

   EXIT WHEN FOUND;

   -- if type is missing, insert and keep looping
   INSERT INTO company_type (company_type)
   VALUES (_toc)
   ON     CONFLICT (company_type) DO NOTHING;
END LOOP;
END
$func$ LANGUAGE plpgsql;
</code>```

dbfiddle here

Related (with detailed explanation):

Is SELECT or INSERT in a function prone to race conditions?

Body:
I have a problem with my procedure. We have 2 tables : companies and typeofcompanies.  Companies have 3 columns ("companyid","companyname","typeofcompany") , typeofcompanies have 2 columns ("typeofcompanyId", "typeofcompany");

This is my code for insert values into companies:

 CREATE OR REPLACE FUNCTION insert_to_companies(c_name VARCHAR(255),toc INTEGER)
      RETURNS VOID AS $$
          DECLARE i integer;
           BEGIN
          FOR i IN SELECT "typeofcompanyId" FROM typeofcompanies LOOP
            IF toc = i THEN insert into public.companies(companyname, typeofcompany) VALUES (c_name,toc);
              END IF;
          END LOOP;
          IF(SELECT companyname FROM companies WHERE companyname = c_name) = NULL THEN insert into public.typeofcompanies(typeofcompany) VALUES (toc);
                                                                             INSERT into public.companies(companyname,typeofcompany) VALUES (c_name,toc);
          END IF;
          END;
    $$ LANGUAGE plpgsql VOLATILE;

So if we haven't typeofcompany we should create it. But when i SELECT insert_to_companies("1",5);  i take  ERROR: column "1" does not exist.   So i think it's very easier problem, but i spent more than 3 hour and can't find problem. Please, i need help....

code for creating table with liquibase

companies:

<databaseChangeLog xmlns = "http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
    <changeSet id="1" author="tiurinvalery@gmail.com" runOnChange="true" >
        <createTable tableName ="companies">
            <column autoIncrement = "true" name = "companyid" type ="BIGINT">
                <constraints primaryKey ="true"></constraints>
            </column>
            <column name="companyname" type="VARCHAR(255)">
            </column>
            <column name="typeofcompany" type="INTEGER">
            </column>
        </createTable>
    </changeSet>
 </databaseChangeLog>

For type of companies:

<databaseChangeLog xmlns = "http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd"  >
    <changeSet id="5" author="tiurinvalery@gmail.com" runOnChange="true" >
        <createTable tableName ="typeofcompanies">
            <column autoIncrement = "true" name = "typeofcompanyId" type ="BIGINT">
                <constraints nullable="false" primaryKey="true"></constraints>
            </column>
            <column name = "typeofcompany" type="VARCHAR(255)">
                <constraints nullable="false"></constraints>
            </column>
        </createTable>
    </changeSet>
</databaseChangeLog>

Body:
Table definitions could look like this:

CREATE TABLE company_type (
   company_type_id serial PRIMARY KEY
 , company_type    text UNIQUE NOT NULL
);

CREATE TABLE company (
   company_id      serial PRIMARY KEY
 , company         text NOT NULL
 , company_type_id int REFERENCES company_type
);

I made a couple of changes:

Not using double-quoted CaMeL-case names. Avoid that, if you can.

Are PostgreSQL column names case-sensitive?

Using integer instead of bigint for PK IDs. I seriously doubt you'll exhaust the key space with company types in this century ...

Using just text. varchar(255) typically is a misunderstanding in Postgres.

The best function (or just query) heavily depends on your use case. DB load, concurrency, exact requirements. If concurrent writes are possible, I suggest this to avoid race conditions:

CREATE OR REPLACE FUNCTION f_insert_to_companies(_c_name text, _toc text)
  RETURNS void AS
$func$
BEGIN
LOOP
   INSERT INTO company(company, company_type_id)
   SELECT _c_name, t.company_type_id
   FROM   company_type t
   WHERE  company_type = _toc;

   EXIT WHEN FOUND;

   -- if type is missing, insert and keep looping
   INSERT INTO company_type (company_type)
   VALUES (_toc)
   ON     CONFLICT (company_type) DO NOTHING;
END LOOP;
END
$func$ LANGUAGE plpgsql;

dbfiddle here

Related (with detailed explanation):

Is SELECT or INSERT in a function prone to race conditions?


问:
Is it possible to send x-request-id back when using istio with zipkin for distributed tracing?
Following the link Istio/Distributed tracing, I can get the tracing working with zipkin.

Currently in order for the client/caller to know about the x-request-id (in case no id is sent, zipkin creates one), he
needs to send it as a part of the request.

This gives him the ability of trace the request. All works well.

However, I am thinking maybe it is not a good idea for the client to send the x-request-id to avoid issues of constraints/duplication.

It would be good if it is possible that at the istio level, one should be able to modify the response headers and send the x-request-id back.

I am not finding such capabilities for istio at present. If there is a way to achieve this, please let me know.

答:
I'm not sure I fully understand your question but I can elaborate a bit on how istio works with respect to tracing:

Tracing means identifying every span or node that is part of the original request, so typically an Id is generated by the istio-ingress and your application should propagate it so each istio-proxy can capture and forward that information to istio-mixer which then lets you use Zipkin or Jaeger to visualize it.

Istio can't know when you make outcalls from your application for which original request it was for unless you do copy the headers.

Does that help/makes sense ?


问:
SQLDataStore with output parameters, getting ParameterName not contained in this SqlParameterCollection error
The ultimate goal of what I am trying to accomplish is this:
Button at the bottom of a material order form Inserts a new record in the material order table with the ProjectID and current date. After the record is inserted, redirect the page to the new order id so it can be modified.

If I take out the OnInserted method that is supposed to grab the SCOPE_IDENTITY() output of the insert, the record inserts fine, but with the call, I keep getting "SQLParameter with ParameterName 'NewOrderID' is not contained by this SqlParameterCollection"

ASPX Formview

```<code><asp:FormView ID="FvFooter" runat="server" DataKeyNames="OrderID"
    DataSourceID="FvMatOrdersSQL" ForeColor="#333333" OnItemCommand="FvFooter_OnItemCommand">
    <ItemTemplate>
        <br/>
        <b>Notes</b>
        <br/>
        <asp:Label ID="TxtNotes" runat="server" BorderStyle="Solid" BorderWidth="1"
        Text='<%# Eval("Notes").ToString().Replace(Environment.NewLine, "<br />") %>'/>
        <br/>
        <asp:LinkButton ID="LbEditNotes" runat="server" CssClass="NoPrint"
            CausesValidation="False" CommandName="Edit" Text="Edit"/>
        <br/>
        <br/>
        <asp:Button ID="DeleteButton" runat="server" CausesValidation="False"
            CssClass="NoPrint" CommandName="DeleteOrder" Text="Delete"/>
         <asp:Button ID="NewButton" runat="server" CausesValidation="True"
            CssClass="NoPrint" CommandName="NewOrder" Text="New Order"/>
         <asp:Button ID="EmailButton" runat="server" CausesValidation="True"
            CssClass="NoPrint" CommandName="Email" Text="Email"/>
    </ItemTemplate>
</asp:FormView>
</code>```

SQL DataSource

```<code><asp:SqlDataSource ID="FvMatOrdersSQL" runat="server" ConnectionString="<%$ ConnectionStrings:ProjectLogicTestConnectionString %>"
    SelectCommand="SELECT mo.OrderID, mo.ProjectID, p.ProjectName, mo.OrderedByEmpID, emp.Name,
        mo.OrderDate, mo.DateNeeded, mo.ReasonID, mor.Description, mo.Notes
            FROM tblMatOrder AS mo
            LEFT OUTER JOIN tblMatOrderReason AS mor ON mo.ReasonID = mor.ReasonID
            INNER JOIN tblProject AS p ON mo.ProjectID = p.ProjectID
            LEFT OUTER JOIN tblEmployee AS emp ON mo.OrderedByEmpID = emp.EmployeeID
            WHERE mo.OrderID = @OrderID"
DeleteCommand="DELETE FROM tblMatOrder WHERE OrderID = @OrderID"
InsertCommand="INSERT INTO tblMatOrder (OrderDate, ProjectID) VALUES (@OrderDate, @ProjectID);
    SELECT @NewOrderID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE tblMatOrder SET OrderDate = @OrderDate, OrderedByEmpID = @OrderedByEmpID,
 DateNeeded = @DateNeeded, ReasonID = @ReasonID, Notes = @Notes
 WHERE OrderID = @OrderID"
 OnInserted="FvMatOrdersSQL_OnInserted">
    <SelectParameters>
        <asp:RouteParameter Name="OrderID" Type="Int32" RouteKey="OrderID"/>
    </SelectParameters>
    <DeleteParameters>
        <asp:Parameter Name="OrderID" Type="Int32" DefaultValue="0"/>
    </DeleteParameters>
    <InsertParameters>
        <asp:Parameter Name="OrderDate" Type="DateTime"/>
        <asp:Parameter Name="ProjectID" Type="Int32"/>
        <asp:Parameter Direction ="Output" Name="NewOrderID" Type="Int32" DefaultValue="0"/>
    </InsertParameters>
    <UpdateParameters>
        <asp:RouteParameter Name="OrderID" Type="Int32" RouteKey="OrderID"/>
        <asp:Parameter Name="OrderDate" Type="DateTime"/>
        <asp:Parameter Name="OrderedByEmpID" Type="Int32"/>
        <asp:Parameter Name="DateNeeded" Type="DateTime"/>
        <asp:Parameter Name="ReasonID" Type="Int32"/>
        <asp:Parameter Name="Notes" Type="String"/>
    </UpdateParameters>
</asp:SqlDataSource>
</code>```

On Button Click codebehind

```<code>protected void FvFooter_OnItemCommand(object sender, FormViewCommandEventArgs e)
        {
            switch (e.CommandName)
            {
                case "DeleteOrder":
                    // Confirmation stuff here
                    break;
                case "NewOrder" when Page.IsValid:
                    Label lblProjectId = (Label)FvHeader.FindControl("LblProjectID");
                    String strOrderDate = DateTime.Now.ToShortDateString();
                    FvMatOrdersSQL.InsertParameters.Clear();
                    FvMatOrdersSQL.InsertParameters.Add("ProjectID", lblProjectId.Text);
                    FvMatOrdersSQL.InsertParameters.Add("OrderDate", strOrderDate);
                    FvMatOrdersSQL.Insert();
                    break;
                case "Email" when Page.IsValid:

                    break;
            }
        }
</code>```

OnInserted codebehind

```<code>protected void FvMatOrdersSQL_OnInserted(object sender, SqlDataSourceStatusEventArgs e)
        {
            String strOrderId = e.Command.Parameters["@NewOrderID"].Value.ToString();
            Response.Redirect("MatOrderDetails.aspx?OrderID=" + strOrderId);
        }
</code>```

I've tried to base as much of my code on the example here https://msdn.microsoft.com/en-us/library/ms228051.aspx but apparently I'm missing something.

答:
I've put yr code and have created a db close to yr select to figure out yr problem, I have to admit it wasn't easy :) please

change this

```<code> FvMatOrdersSQL.InsertParameters.Clear();
 FvMatOrdersSQL.InsertParameters.Add("ProjectID", lblProjectId.Text);
 FvMatOrdersSQL.InsertParameters.Add("OrderDate", strOrderDate);
</code>```

To:

```<code>FvMatOrdersSQL.InsertParameters["ProjectID"].DefaultValue = lblProjectId.Text;
FvMatOrdersSQL.InsertParameters["OrderDate"].DefaultValue = strOrderDate;
</code>```

Don't remove the params which you've already created in the UI!

Body:
The ultimate goal of what I am trying to accomplish is this:
Button at the bottom of a material order form Inserts a new record in the material order table with the ProjectID and current date. After the record is inserted, redirect the page to the new order id so it can be modified.

If I take out the OnInserted method that is supposed to grab the SCOPE_IDENTITY() output of the insert, the record inserts fine, but with the call, I keep getting "SQLParameter with ParameterName 'NewOrderID' is not contained by this SqlParameterCollection"

ASPX Formview

<asp:FormView ID="FvFooter" runat="server" DataKeyNames="OrderID"
    DataSourceID="FvMatOrdersSQL" ForeColor="#333333" OnItemCommand="FvFooter_OnItemCommand">
    <ItemTemplate>

        Notes

        <asp:Label ID="TxtNotes" runat="server" BorderStyle="Solid" BorderWidth="1"
        Text='<%# Eval("Notes").ToString().Replace(Environment.NewLine, "
") %>'/>

        <asp:LinkButton ID="LbEditNotes" runat="server" CssClass="NoPrint"
            CausesValidation="False" CommandName="Edit" Text="Edit"/>

        <asp:Button ID="DeleteButton" runat="server" CausesValidation="False"
            CssClass="NoPrint" CommandName="DeleteOrder" Text="Delete"/>
         <asp:Button ID="NewButton" runat="server" CausesValidation="True"
            CssClass="NoPrint" CommandName="NewOrder" Text="New Order"/>
         <asp:Button ID="EmailButton" runat="server" CausesValidation="True"
            CssClass="NoPrint" CommandName="Email" Text="Email"/>
    </ItemTemplate>
</asp:FormView>

SQL DataSource

<asp:SqlDataSource ID="FvMatOrdersSQL" runat="server" ConnectionString="<%$ ConnectionStrings:ProjectLogicTestConnectionString %>"
    SelectCommand="SELECT mo.OrderID, mo.ProjectID, p.ProjectName, mo.OrderedByEmpID, emp.Name,
        mo.OrderDate, mo.DateNeeded, mo.ReasonID, mor.Description, mo.Notes
            FROM tblMatOrder AS mo
            LEFT OUTER JOIN tblMatOrderReason AS mor ON mo.ReasonID = mor.ReasonID
            INNER JOIN tblProject AS p ON mo.ProjectID = p.ProjectID
            LEFT OUTER JOIN tblEmployee AS emp ON mo.OrderedByEmpID = emp.EmployeeID
            WHERE mo.OrderID = @OrderID"
DeleteCommand="DELETE FROM tblMatOrder WHERE OrderID = @OrderID"
InsertCommand="INSERT INTO tblMatOrder (OrderDate, ProjectID) VALUES (@OrderDate, @ProjectID);
    SELECT @NewOrderID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE tblMatOrder SET OrderDate = @OrderDate, OrderedByEmpID = @OrderedByEmpID,
 DateNeeded = @DateNeeded, ReasonID = @ReasonID, Notes = @Notes
 WHERE OrderID = @OrderID"
 OnInserted="FvMatOrdersSQL_OnInserted">
    <SelectParameters>
        <asp:RouteParameter Name="OrderID" Type="Int32" RouteKey="OrderID"/>
    </SelectParameters>
    <DeleteParameters>
        <asp:Parameter Name="OrderID" Type="Int32" DefaultValue="0"/>
    </DeleteParameters>
    <InsertParameters>
        <asp:Parameter Name="OrderDate" Type="DateTime"/>
        <asp:Parameter Name="ProjectID" Type="Int32"/>
        <asp:Parameter Direction ="Output" Name="NewOrderID" Type="Int32" DefaultValue="0"/>
    </InsertParameters>
    <UpdateParameters>
        <asp:RouteParameter Name="OrderID" Type="Int32" RouteKey="OrderID"/>
        <asp:Parameter Name="OrderDate" Type="DateTime"/>
        <asp:Parameter Name="OrderedByEmpID" Type="Int32"/>
        <asp:Parameter Name="DateNeeded" Type="DateTime"/>
        <asp:Parameter Name="ReasonID" Type="Int32"/>
        <asp:Parameter Name="Notes" Type="String"/>
    </UpdateParameters>
</asp:SqlDataSource>

On Button Click codebehind

protected void FvFooter_OnItemCommand(object sender, FormViewCommandEventArgs e)
        {
            switch (e.CommandName)
            {
                case "DeleteOrder":
                    // Confirmation stuff here
                    break;
                case "NewOrder" when Page.IsValid:
                    Label lblProjectId = (Label)FvHeader.FindControl("LblProjectID");
                    String strOrderDate = DateTime.Now.ToShortDateString();
                    FvMatOrdersSQL.InsertParameters.Clear();
                    FvMatOrdersSQL.InsertParameters.Add("ProjectID", lblProjectId.Text);
                    FvMatOrdersSQL.InsertParameters.Add("OrderDate", strOrderDate);
                    FvMatOrdersSQL.Insert();
                    break;
                case "Email" when Page.IsValid:

                    break;
            }
        }

OnInserted codebehind

protected void FvMatOrdersSQL_OnInserted(object sender, SqlDataSourceStatusEventArgs e)
        {
            String strOrderId = e.Command.Parameters["@NewOrderID"].Value.ToString();
            Response.Redirect("MatOrderDetails.aspx?OrderID=" + strOrderId);
        }

I've tried to base as much of my code on the example here https://msdn.microsoft.com/en-us/library/ms228051.aspx but apparently I'm missing something.

Body:
I've put yr code and have created a db close to yr select to figure out yr problem, I have to admit it wasn't easy :) please

change this

 FvMatOrdersSQL.InsertParameters.Clear();
 FvMatOrdersSQL.InsertParameters.Add("ProjectID", lblProjectId.Text);
 FvMatOrdersSQL.InsertParameters.Add("OrderDate", strOrderDate);

To:

FvMatOrdersSQL.InsertParameters["ProjectID"].DefaultValue = lblProjectId.Text;
FvMatOrdersSQL.InsertParameters["OrderDate"].DefaultValue = strOrderDate;

Don't remove the params which you've already created in the UI!


问:
While loop isn't outputting the correct data
So I made corrections to my code as you all suggested. I'm able to get into the loop however once I input a correct name I'm still not able to get out of it. Any suggestions?
Here's what I got:

```<code>import csv

full_name = input('Enter your full name: ').lower()

with open('Report1.csv') as csvfile:
    hour_summation = {}
    read_csv = csv.reader(csvfile, delimiter=',')
    for row in read_csv:
        while (' '.join((row[0], row[1]))).lower() != full_name.strip().lower():
            print('Name is not in system')
            full_name = input('Enter your full name: ').lower()
        if(' '.join((row[0], row[1]))).lower() == full_name.strip().lower():
            hour_summation[row[2]] = hour_summation.get(row[2], 0) + int(float(row[3]))
print('This is {} full hours report:'.format(full_name))
for k, v in hour_summation.items():
    print(k + ': ' + str(v) + ' hours')
</code>```

Here's the result when I give an input:
fyi. Steve Miller is not in the csv file so that first response is correct. However, Sri Mantri is in the file and it should continue on and print out all the listings under her name.

```<code>Enter your full name: Steve Miller
Name is not in system
Enter your full name: Sri Mantri
Name is not in system
</code>```

Here's what the output should look like when the code runs.

```<code>Enter your full name: Sri mantri
This is sri mantri full hours report:
Beeline Blank: 28 hours
SRV-0001 Service Requests for Base and Direct Services: 4 hours
SUP-0001 Support Requests with a CISM Ticket: 129 hours
SUP-2503 Web Application Maintenance & Support: 72 hours
0026184229 Margin Controlling Java Rewrite: 4 hours
0033472751 PRE-AFE 2017 - CMS Enhancements: 2 hours
0033472863 PRE-AFE 2017 - BPM Enhancements: 67 hours
APP-10008 Pre-Series (Non-Mainframe): 4 hours
APP-10146 Logistics (Non-Mainframe): 3 hours
APP-10195 Vehicle Labor System (Mainframe): 3 hours
APP-10354 Web PartsPro (Non-Mainframe): 1 hours
APP-10431 VIPService (Non-Mainframe): 1 hours
APP-10432 VIPService (Mainframe): 3 hours
APP-10536 Truck Invoice Adjustments (Mainframe): 2 hours
</code>```

and the csv looks like this:

```<code>   First Name   Last Name   Activity    Hours
Sri Mantri  SUP-2503 Web Application Maintenance & Support  11
Sri Mantri  SUP-2503 Web Application Maintenance & Support  3
Sri Mantri  SUP-2503 Web Application Maintenance & Support  5
Sri Mantri  SUP-2503 Web Application Maintenance & Support  2
Jeff    Moore   SUP-2503 Web Application Maintenance & Support  3
David   Ayers   SUP-2507  NAFTA MFTS OS Support 10
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    4
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    3
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    1
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    1
Jeff    Moore   0024480049 Fuel Tanks (infrastructure) - time tracking  1
Jeff    Moore   0024480049 Fuel Tanks (infrastructure) - time tracking  1
Jeff    Moore   0024480049 Fuel Tanks (infrastructure) - time tracking  4
</code>```

答:
Inside this code you use name to get name but later you use full_name

```<code> while (' '.join((row[0], row[1]))).lower() != full_name.strip():
        print('Name is not in system')
        name = input('Enter your full name: ')
</code>```

You should use only full_name (and it needs lower())

```<code> while (' '.join((row[0], row[1]))).lower() != full_name.strip():
        print('Name is not in system')
        full_name = input('Enter your full name: ').lower() # <-- full_name
</code>```

Or convert name to full_name

```<code> while (' '.join((row[0], row[1]))).lower() != full_name.strip():
        print('Name is not in system')
        name = input('Enter your full name: ')
        full_name = name.lower() # <-- full_name
</code>```

Body:
So I made corrections to my code as you all suggested. I'm able to get into the loop however once I input a correct name I'm still not able to get out of it. Any suggestions?
Here's what I got:

import csv

full_name = input('Enter your full name: ').lower()

with open('Report1.csv') as csvfile:
    hour_summation = {}
    read_csv = csv.reader(csvfile, delimiter=',')
    for row in read_csv:
        while (' '.join((row[0], row[1]))).lower() != full_name.strip().lower():
            print('Name is not in system')
            full_name = input('Enter your full name: ').lower()
        if(' '.join((row[0], row[1]))).lower() == full_name.strip().lower():
            hour_summation[row[2]] = hour_summation.get(row[2], 0) + int(float(row[3]))
print('This is {} full hours report:'.format(full_name))
for k, v in hour_summation.items():
    print(k + ': ' + str(v) + ' hours')

Here's the result when I give an input:
fyi. Steve Miller is not in the csv file so that first response is correct. However, Sri Mantri is in the file and it should continue on and print out all the listings under her name.

Enter your full name: Steve Miller
Name is not in system
Enter your full name: Sri Mantri
Name is not in system

Here's what the output should look like when the code runs.

Enter your full name: Sri mantri
This is sri mantri full hours report:
Beeline Blank: 28 hours
SRV-0001 Service Requests for Base and Direct Services: 4 hours
SUP-0001 Support Requests with a CISM Ticket: 129 hours
SUP-2503 Web Application Maintenance & Support: 72 hours
0026184229 Margin Controlling Java Rewrite: 4 hours
0033472751 PRE-AFE 2017 - CMS Enhancements: 2 hours
0033472863 PRE-AFE 2017 - BPM Enhancements: 67 hours
APP-10008 Pre-Series (Non-Mainframe): 4 hours
APP-10146 Logistics (Non-Mainframe): 3 hours
APP-10195 Vehicle Labor System (Mainframe): 3 hours
APP-10354 Web PartsPro (Non-Mainframe): 1 hours
APP-10431 VIPService (Non-Mainframe): 1 hours
APP-10432 VIPService (Mainframe): 3 hours
APP-10536 Truck Invoice Adjustments (Mainframe): 2 hours

and the csv looks like this:

   First Name   Last Name   Activity    Hours
Sri Mantri  SUP-2503 Web Application Maintenance & Support  11
Sri Mantri  SUP-2503 Web Application Maintenance & Support  3
Sri Mantri  SUP-2503 Web Application Maintenance & Support  5
Sri Mantri  SUP-2503 Web Application Maintenance & Support  2
Jeff    Moore   SUP-2503 Web Application Maintenance & Support  3
David   Ayers   SUP-2507  NAFTA MFTS OS Support 10
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    4
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    3
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    1
Prasanth    Musunuru    0020826809 Vertex 6.0 at the NDC    1
Jeff    Moore   0024480049 Fuel Tanks (infrastructure) - time tracking  1
Jeff    Moore   0024480049 Fuel Tanks (infrastructure) - time tracking  1
Jeff    Moore   0024480049 Fuel Tanks (infrastructure) - time tracking  4

Body:
Inside this code you use name to get name but later you use full_name

 while (' '.join((row[0], row[1]))).lower() != full_name.strip():
        print('Name is not in system')
        name = input('Enter your full name: ')

You should use only full_name (and it needs lower())

 while (' '.join((row[0], row[1]))).lower() != full_name.strip():
        print('Name is not in system')
        full_name = input('Enter your full name: ').lower() # <-- full_name

Or convert name to full_name

 while (' '.join((row[0], row[1]))).lower() != full_name.strip():
        print('Name is not in system')
        name = input('Enter your full name: ')
        full_name = name.lower() # <-- full_name


问:
Wanting to create a specific layout in JFrame (JAVA)
So I'm procrastinating studying for finals and thought I should make a simple game instead after taking an intro to Java class. We briefly learned how to use JFrames so I wanted to use this for my game. I'm making a simple clicker game similar to cookie clicker or any game in that same genre. Right now my GUI looks like this. I want my GUI to look similar to this where the menu buttons are on different sides of a central button. I tried to use different layout managers and none of them worked for what I was doing. I have tried flow layout, box layout, and grid layout. The grid one got me the closest but still didn't work well since everything was the same size and were just a grid, so I couldn't have that central button. Does anyone have any tips for me?

This is my launcher class

```<code>import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JFrame;

public class Launcher {
    public static void main(String[] args) {
        Game theGame = new Game();
        theGame.setSize(650,500);
        theGame.setVisible(true);
        theGame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        theGame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentHidden(ComponentEvent e) {
                theGame.createSaveFile();
                System.exit(1);
            }
        });
    }
}
</code>```

this is my game class

```<code>import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.PrintWriter;
    import java.util.*;
    import java.util.Timer;

    public class Game extends JFrame {
        Buying buy = new Buying();
        //creates an instance of SMUQuest
        private int roundNumber = 1;

        //widgets
        JLabel money;
        JButton clicker;
        JButton upgradeClicker;
        JButton firstPurchase;
        JButton secondPurchase;
        JButton thirdPurchase;
        JButton fourthPurchase;
        JButton fifthPurchase;
        JButton sixthPurchase;
        JLabel firstPurchase$PS;
        JLabel firstPurchasePrice;
        JLabel firstPerSecond;

        public Game() {
            super("Clicker Game");
            checkSaveFile();
            setLayout(new FlowLayout());
            clicker = new JButton("CLICK ME FOR 1 POINT!");
            add(clicker);
            clicker.addActionListener(new MyInner());
            upgradeClicker = new JButton("Add 1 to your clicking power for $" + buy.getClickerPrice());
            add(upgradeClicker);
            upgradeClicker.addActionListener(new MyInner());
            money = new JLabel("" + buy.getMoney());
            add(money);
            firstPurchasePrice = new JLabel("" + buy.getFirstBuyPrice());
            add(firstPurchasePrice);
            firstPurchase = new JButton("First Property!");
            add(firstPurchase);
            firstPurchase.addActionListener(new MyInner());
            firstPurchase$PS = new JLabel("" + buy.getFirstBuy$PS());
            add(firstPurchase$PS);

            //timer to add money every second
            Timer t = new Timer();
            t.schedule(new TimerTask() {
                @Override
                public void run() {
                   buy.moneyPS();
                   money.setText("You have $" + buy.getMoney());
                }
            }, 0, 1000);
        }

        private class MyInner implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == firstPurchase) {
                    if(buy.getMoney() >= buy.getFirstBuyPrice()) {
                    buy.subtractMoney(buy.getFirstBuyPrice());
                    buy.setFirstBuy$PS(1);
                    buy.setFirstBuyPrice(2);
                    firstPurchase$PS.setText("$" + buy.getFirstBuy$PS());
                    firstPurchasePrice.setText("$" + buy.getFirstBuyPrice());
                    money.setText("You have $" + buy.getMoney());
                    }
                }
                if (e.getSource() == clicker) {
                    buy.addMoney(buy.getClickerStrength());
                    money.setText("You have $" + buy.getMoney());
                }
                if (e.getSource() == upgradeClicker) {
                    if(buy.getMoney() >= buy.getClickerPrice()) {
                    buy.subtractMoney(buy.getClickerPrice());
                    buy.setClickerPrice();
                    upgradeClicker.setText("Add 1 to your clicking power for $" + buy.getClickerPrice());
                    buy.setClickerStrength();
                    }
                }
            }
        }
        public void checkSaveFile() {
            File inputFile = new File("SaveGame.txt");
            try {
                Scanner input = new Scanner(inputFile);
                    int line = input.nextInt();
                    if(line > 0)
                        buy.setMoney(line);
            }
            catch(FileNotFoundException exp) {
                System.out.println("File not Found Exception. Make sure the input file exists.");
            }
        }
        public void createSaveFile() {
            File outputFile = new File("SaveGame.txt");//creates a new file
            try {
                PrintWriter pWriter = new PrintWriter(outputFile);
                pWriter.println(buy.getMoney());
                pWriter.close();
            }
            catch(FileNotFoundException exp) {
                System.out.println("File not found.");
            }
        }
    }
</code>```

This is my class for setting values to variables and such

```<code>public class Buying {
            private int firstBuy$PS;
            private int firstBuyPrice;
            private int money = 1;
            private int clickerStrength = 1;
            private int clickerPrice =10;

            public int getFirstBuy$PS() {
                return firstBuy$PS;
            }

            public void setFirstBuy$PS(int x) {
                firstBuy$PS += x;
            }

            public int getFirstBuyPrice() {
                return firstBuyPrice;
            }

            public void setFirstBuyPrice(int x) {
                firstBuyPrice += x;
            }
            public void moneyPS() {
                money += getFirstBuy$PS();
            }
            public int getMoney() {
                return money;
            }
            public void subtractMoney(int x) {
                money -= x;
            }
            public void addMoney(int x) {
                money += x;
            }
            public void setMoney(int x) {
                money = x;
            }
            public void setClickerStrength() {
                clickerStrength += 1;
            }
            public int getClickerStrength() {
                return clickerStrength;
            }
            public int getClickerPrice() {
                return clickerPrice;
            }
            public void setClickerPrice() {
                clickerPrice*=1.2323452;
            }
        }
</code>```

Edit: Put code in the question and not a link to my Github

答:
Since it seems you are just begining to play with GUIs i strongly suggest you use a GUI manager like swing.

Other than that all i saw in your code is you creating the components and adding them to your layout without telling the program where to put them. That is the reason your game look like that.

I think using a GridPane can totally do the job. My only hint is that a grid definitely has a place for a central button. Look at the image of how you want your game to look and try to see a grid there.

More than this and i think i would spoon feed you too much and that isnt good.

Body:
So I'm procrastinating studying for finals and thought I should make a simple game instead after taking an intro to Java class. We briefly learned how to use JFrames so I wanted to use this for my game. I'm making a simple clicker game similar to cookie clicker or any game in that same genre. Right now my GUI looks like this. I want my GUI to look similar to this where the menu buttons are on different sides of a central button. I tried to use different layout managers and none of them worked for what I was doing. I have tried flow layout, box layout, and grid layout. The grid one got me the closest but still didn't work well since everything was the same size and were just a grid, so I couldn't have that central button. Does anyone have any tips for me?

This is my launcher class

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JFrame;

public class Launcher {
    public static void main(String[] args) {
        Game theGame = new Game();
        theGame.setSize(650,500);
        theGame.setVisible(true);
        theGame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        theGame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentHidden(ComponentEvent e) {
                theGame.createSaveFile();
                System.exit(1);
            }
        });
    }
}

this is my game class

import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.PrintWriter;
    import java.util.*;
    import java.util.Timer;

    public class Game extends JFrame {
        Buying buy = new Buying();
        //creates an instance of SMUQuest
        private int roundNumber = 1;

        //widgets
        JLabel money;
        JButton clicker;
        JButton upgradeClicker;
        JButton firstPurchase;
        JButton secondPurchase;
        JButton thirdPurchase;
        JButton fourthPurchase;
        JButton fifthPurchase;
        JButton sixthPurchase;
        JLabel firstPurchase$PS;
        JLabel firstPurchasePrice;
        JLabel firstPerSecond;

        public Game() {
            super("Clicker Game");
            checkSaveFile();
            setLayout(new FlowLayout());
            clicker = new JButton("CLICK ME FOR 1 POINT!");
            add(clicker);
            clicker.addActionListener(new MyInner());
            upgradeClicker = new JButton("Add 1 to your clicking power for $" + buy.getClickerPrice());
            add(upgradeClicker);
            upgradeClicker.addActionListener(new MyInner());
            money = new JLabel("" + buy.getMoney());
            add(money);
            firstPurchasePrice = new JLabel("" + buy.getFirstBuyPrice());
            add(firstPurchasePrice);
            firstPurchase = new JButton("First Property!");
            add(firstPurchase);
            firstPurchase.addActionListener(new MyInner());
            firstPurchase$PS = new JLabel("" + buy.getFirstBuy$PS());
            add(firstPurchase$PS);

            //timer to add money every second
            Timer t = new Timer();
            t.schedule(new TimerTask() {
                @Override
                public void run() {
                   buy.moneyPS();
                   money.setText("You have $" + buy.getMoney());
                }
            }, 0, 1000);
        }

        private class MyInner implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == firstPurchase) {
                    if(buy.getMoney() >= buy.getFirstBuyPrice()) {
                    buy.subtractMoney(buy.getFirstBuyPrice());
                    buy.setFirstBuy$PS(1);
                    buy.setFirstBuyPrice(2);
                    firstPurchase$PS.setText("$" + buy.getFirstBuy$PS());
                    firstPurchasePrice.setText("$" + buy.getFirstBuyPrice());
                    money.setText("You have $" + buy.getMoney());
                    }
                }
                if (e.getSource() == clicker) {
                    buy.addMoney(buy.getClickerStrength());
                    money.setText("You have $" + buy.getMoney());
                }
                if (e.getSource() == upgradeClicker) {
                    if(buy.getMoney() >= buy.getClickerPrice()) {
                    buy.subtractMoney(buy.getClickerPrice());
                    buy.setClickerPrice();
                    upgradeClicker.setText("Add 1 to your clicking power for $" + buy.getClickerPrice());
                    buy.setClickerStrength();
                    }
                }
            }
        }
        public void checkSaveFile() {
            File inputFile = new File("SaveGame.txt");
            try {
                Scanner input = new Scanner(inputFile);
                    int line = input.nextInt();
                    if(line > 0)
                        buy.setMoney(line);
            }
            catch(FileNotFoundException exp) {
                System.out.println("File not Found Exception. Make sure the input file exists.");
            }
        }
        public void createSaveFile() {
            File outputFile = new File("SaveGame.txt");//creates a new file
            try {
                PrintWriter pWriter = new PrintWriter(outputFile);
                pWriter.println(buy.getMoney());
                pWriter.close();
            }
            catch(FileNotFoundException exp) {
                System.out.println("File not found.");
            }
        }
    }

This is my class for setting values to variables and such

public class Buying {
            private int firstBuy$PS;
            private int firstBuyPrice;
            private int money = 1;
            private int clickerStrength = 1;
            private int clickerPrice =10;

            public int getFirstBuy$PS() {
                return firstBuy$PS;
            }

            public void setFirstBuy$PS(int x) {
                firstBuy$PS += x;
            }

            public int getFirstBuyPrice() {
                return firstBuyPrice;
            }

            public void setFirstBuyPrice(int x) {
                firstBuyPrice += x;
            }
            public void moneyPS() {
                money += getFirstBuy$PS();
            }
            public int getMoney() {
                return money;
            }
            public void subtractMoney(int x) {
                money -= x;
            }
            public void addMoney(int x) {
                money += x;
            }
            public void setMoney(int x) {
                money = x;
            }
            public void setClickerStrength() {
                clickerStrength += 1;
            }
            public int getClickerStrength() {
                return clickerStrength;
            }
            public int getClickerPrice() {
                return clickerPrice;
            }
            public void setClickerPrice() {
                clickerPrice*=1.2323452;
            }
        }

Edit: Put code in the question and not a link to my Github


问:
Standardization/Normalization test data in Python
I'm working in a sklearn homework and I don't understand why one should standardize and normalize the test data with the training mean and sd. How can I implement this in Python?
Here is my implementation for the train data:

```<code>digits = sklearn.datasets.load_digits()
X= digits.data
Y= digits.target
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3,train_size=0.7)
std_scale = preprocessing.StandardScaler().fit(X_train)
X_train_std = std_scale.transform(X_train)
#X_test_std=??
</code>```

For the train i think it's correct, but for the test?

答:
Why?

Because your classifier/regressor will be trained on those standardizes values. You don't want to use your trained-classifier to predict data which has other statistics.

How:

```<code>std_scale = preprocessing.StandardScaler().fit(X_train)
X_train_std = std_scale.transform(X_train)
X_test_std  = std_scale.transform(X_test)
</code>```

Fitting once, transforming whatever you need to transform. That's the advantage of the class-based StandardScaler (which you already had chosen) compared to scale which does not hold the needed information needed for applying transformations (based on these statistics obtained during fit) at a later time.

Body:
I'm working in a sklearn homework and I don't understand why one should standardize and normalize the test data with the training mean and sd. How can I implement this in Python?
Here is my implementation for the train data:

digits = sklearn.datasets.load_digits()
X= digits.data
Y= digits.target
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3,train_size=0.7)
std_scale = preprocessing.StandardScaler().fit(X_train)
X_train_std = std_scale.transform(X_train)
#X_test_std=??

For the train i think it's correct, but for the test?

Body:
Why?

Because your classifier/regressor will be trained on those standardizes values. You don't want to use your trained-classifier to predict data which has other statistics.

How:

std_scale = preprocessing.StandardScaler().fit(X_train)
X_train_std = std_scale.transform(X_train)
X_test_std  = std_scale.transform(X_test)

Fitting once, transforming whatever you need to transform. That's the advantage of the class-based StandardScaler (which you already had chosen) compared to scale which does not hold the needed information needed for applying transformations (based on these statistics obtained during fit) at a later time.


问:
How to split a huge folder?
We have a folder on Windows that's ... huge. I ran "dir > list.txt". The command lost response after 1.5 hours. The output file is about 200 MB. It shows there're at least 2.8 million files. I know the situation is stupid but let's focus the problem itself. If I have such a folder, how can I split it to some "manageable" sub-folders? Surprisingly all the solutions I have come up with all involve getting all the files in the folder at some point, which is a no-no in my case. Any suggestions?

Thank Keith Hill and Mehrdad. I accepted Keith's answer because that's exactly what I wanted to do but I couldn't quite get PS working quickly.

With Mehrdad's tip, I wrote this little program. It took 7+ hours to move 2.8 million files. So the initial dir command did finish. But somehow it didn't return to console.

```<code>namespace SplitHugeFolder
{
    class Program
    {
        static void Main(string[] args)
        {
            var destination = args[1];

            if (!Directory.Exists(destination))
                Directory.CreateDirectory(destination);

            var di = new DirectoryInfo(args[0]);

            var batchCount = int.Parse(args[2]);
            int currentBatch = 0;

            string targetFolder = GetNewSubfolder(destination);

            foreach (var fileInfo in di.EnumerateFiles())
            {
                if (currentBatch == batchCount)
                {
                    Console.WriteLine("New Batch...");
                    currentBatch = 0;
                    targetFolder = GetNewSubfolder(destination);
                }

                var source = fileInfo.FullName;
                var target = Path.Combine(targetFolder, fileInfo.Name);
                File.Move(source, target);
                currentBatch++;
            }
        }

        private static string GetNewSubfolder(string parent)
        {
            string newFolder;
            do
            {
                newFolder = Path.Combine(parent, Path.GetRandomFileName());
            } while (Directory.Exists(newFolder));
            Directory.CreateDirectory(newFolder);
            return newFolder;
        }
    }
}
</code>```

答:
I use Get-ChildItem to index my whole C: drive every night into c:\filelist.txt. That's about 580,000 files and the resulting file size is ~60MB.  Admittedly I'm on Win7 x64 with 8 GB of RAM.  That said, you might try something like this:

```<code>md c:\newdir
Get-ChildItem C:\hugedir -r |
    Foreach -Begin {$i = $j = 0} -Process {
        if ($i++ % 100000 -eq 0) {
            $dest = "C:\newdir\dir$j"
            md $dest
            $j++
        }
        Move-Item $_ $dest
    }
</code>```

The key is to do the move in a streaming manner. That is, don't collect up all the Get-ChildItem results into a single variable and then proceed.  That would require all 2.8 million FileInfos to be in memory at once.  Also, if you use the Name parameter on Get-ChildItem it will output a single string containing the file's path relative to the base dir.  Even then, perhaps this size will just overwhelm the memory available to you. And no doubt, it will take quite a while to execute.  IIRC correctly, my indexing script takes several hours.

If it does work, you should wind up with c:\newdir\dir0 thru dir28 but then again, I haven't tested this script at all so your mileage may vary.  BTW this approach assumes that you're huge dir is a pretty flat dir.

Update: Using the Name parameter is almost twice as slow so don't use that parameter.

ContentLicense: CC BY-SA 2.5

Title: How to split a huge folder?

Body:
We have a folder on Windows that's ... huge. I ran "dir > list.txt". The command lost response after 1.5 hours. The output file is about 200 MB. It shows there're at least 2.8 million files. I know the situation is stupid but let's focus the problem itself. If I have such a folder, how can I split it to some "manageable" sub-folders? Surprisingly all the solutions I have come up with all involve getting all the files in the folder at some point, which is a no-no in my case. Any suggestions?

Thank Keith Hill and Mehrdad. I accepted Keith's answer because that's exactly what I wanted to do but I couldn't quite get PS working quickly.

With Mehrdad's tip, I wrote this little program. It took 7+ hours to move 2.8 million files. So the initial dir command did finish. But somehow it didn't return to console.

namespace SplitHugeFolder
{
    class Program
    {
        static void Main(string[] args)
        {
            var destination = args[1];

            if (!Directory.Exists(destination))
                Directory.CreateDirectory(destination);

            var di = new DirectoryInfo(args[0]);

            var batchCount = int.Parse(args[2]);
            int currentBatch = 0;

            string targetFolder = GetNewSubfolder(destination);

            foreach (var fileInfo in di.EnumerateFiles())
            {
                if (currentBatch == batchCount)
                {
                    Console.WriteLine("New Batch...");
                    currentBatch = 0;
                    targetFolder = GetNewSubfolder(destination);
                }

                var source = fileInfo.FullName;
                var target = Path.Combine(targetFolder, fileInfo.Name);
                File.Move(source, target);
                currentBatch++;
            }
        }

        private static string GetNewSubfolder(string parent)
        {
            string newFolder;
            do
            {
                newFolder = Path.Combine(parent, Path.GetRandomFileName());
            } while (Directory.Exists(newFolder));
            Directory.CreateDirectory(newFolder);
            return newFolder;
        }
    }
}

Body:
I use Get-ChildItem to index my whole C: drive every night into c:\filelist.txt. That's about 580,000 files and the resulting file size is ~60MB.  Admittedly I'm on Win7 x64 with 8 GB of RAM.  That said, you might try something like this:

md c:\newdir
Get-ChildItem C:\hugedir -r |
    Foreach -Begin {$i = $j = 0} -Process {
        if ($i++ % 100000 -eq 0) {
            $dest = "C:\newdir\dir$j"
            md $dest
            $j++
        }
        Move-Item $_ $dest
    }

The key is to do the move in a streaming manner. That is, don't collect up all the Get-ChildItem results into a single variable and then proceed.  That would require all 2.8 million FileInfos to be in memory at once.  Also, if you use the Name parameter on Get-ChildItem it will output a single string containing the file's path relative to the base dir.  Even then, perhaps this size will just overwhelm the memory available to you. And no doubt, it will take quite a while to execute.  IIRC correctly, my indexing script takes several hours.

If it does work, you should wind up with c:\newdir\dir0 thru dir28 but then again, I haven't tested this script at all so your mileage may vary.  BTW this approach assumes that you're huge dir is a pretty flat dir.

Update: Using the Name parameter is almost twice as slow so don't use that parameter.