问:
Use gdal.Open to open an in-memory GDAL Dataset
I have a GDAL dataset that exists only in memory (inmem_ds):

```<code>In: gdal.Info(inmem_ds)
Out:
('Driver: NUMPY/Numeric Python Array\n'
 'Files: none associated\n'
 'Size is 500, 500\n'
 'Coordinate System is:\n'
 'PROJCS["WGS 84 / UTM zone 19N",\n'
 '    GEOGCS["WGS 84",\n'
 '        DATUM["WGS_1984",\n'
 '            SPHEROID["WGS 84",6378137,298.257223563,\n'
 '                AUTHORITY["EPSG","7030"]],\n'
 '            AUTHORITY["EPSG","6326"]],\n'
 '        PRIMEM["Greenwich",0,\n'
 '            AUTHORITY["EPSG","8901"]],\n'
 '        UNIT["degree",0.0174532925199433,\n'
 '            AUTHORITY["EPSG","9122"]],\n'
 '        AUTHORITY["EPSG","4326"]],\n'
 '    PROJECTION["Transverse_Mercator"],\n'
 '    PARAMETER["latitude_of_origin",0],\n'
 '    PARAMETER["central_meridian",-69],\n'
 '    PARAMETER["scale_factor",0.9996],\n'
 '    PARAMETER["false_easting",500000],\n'
 '    PARAMETER["false_northing",0],\n'
 '    UNIT["metre",1,\n'
 '        AUTHORITY["EPSG","9001"]],\n'
 '    AXIS["Easting",EAST],\n'
 '    AXIS["Northing",NORTH],\n'
 '    AUTHORITY["EPSG","32619"]]\n'
 'Origin = (617085.000000000000000,-1512585.000000000000000)\n'
 'Pixel Size = (30.000000000000000,-30.000000000000000)\n'
 'Corner Coordinates:\n'
 'Upper Left  (  617085.000,-1512585.000) ( 67d55\' 2.38"W, 13d40\'47.58"S)\n'
 'Lower Left  (  617085.000,-1527585.000) ( 67d55\' 0.13"W, 13d48\'55.77"S)\n'
 'Upper Right (  632085.000,-1512585.000) ( 67d46\'43.12"W, 13d40\'45.26"S)\n'
 'Lower Right (  632085.000,-1527585.000) ( 67d46\'40.59"W, 13d48\'53.42"S)\n'
 'Center      (  624585.000,-1520085.000) ( 67d50\'51.55"W, 13d44\'50.54"S)\n'
 'Band 1 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 2 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 3 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 4 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 5 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 6 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 7 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 8 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n')
</code>```

Now I want to pass this dataset directly to an external Python library that uses gdal.Open() to open its input datasets. So I need a physical file path that I can pass to gdal.Open(). But I don´t want to write the in-memory GDAL dataset to disk in order to save IO time.

Is there any way to pass an in-memory dataset to gdal.Open()?

I tried to use a VRT dataset but it does not work:

```<code>drv = gdal.GetDriverByName("VRT")
vrt = drv.CreateCopy("/mypath/test.vrt", inmem_ds)
type(vrt.ReadAsArray()) # numpy.ndarray -> works

gdal.Open('/mypath/test.vrt') # None, last GDAL error: Exception: Error reading file:  Missing <SourceFilename> element in VRTRasterBand.
</code>```

The saved VRT file (mypath/test.vrt) looks like this:

```<code><VRTDataset rasterXSize="500" rasterYSize="500">
  <SRS>PROJCS["WGS 84 / UTM zone 19N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-69],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32619"]]</SRS>
  <GeoTransform>  6.1708500000000000e+05,  3.0000000000000000e+01,  0.0000000000000000e+00, -1.5125850000000000e+06,  0.0000000000000000e+00, -3.0000000000000000e+01</GeoTransform>
  <VRTRasterBand dataType="Int16" band="1">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>1</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="2">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>2</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="3">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>3</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="4">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>4</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="5">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>5</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="6">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>6</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="7">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>7</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="8">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>8</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
</VRTDataset>
</code>```

答:
You can write the VRT to memory by using the vsimem prefix, beware that the data actually gets written to memory, so any format other then VRT can increase the memory significantly, depending on the actual filesize.

Also note that the in-memory file remains, even after closing the dataset handle. So you need to unlink it yourself when your done using it, or it will stay memory.

Therefore keep track of the in-mem locations you are using, so you can unlink them properly. Writing to an existing vsimem location, before its 'unlinked' wont work, and remain the original file. That can be a bit of a gotcha.

To output either a file on-disk, or an already open Dataset to an in-mem VRT:

```<code>ds = gdal.Translate('/vsimem/inmem.vrt', some_file_or_dataset, format='VRT')
print(ds.ReadAsArray().shape)
ds = None
</code>```

Open it again:

```<code>ds2 = gdal.Open('/vsimem/inmem.vrt')
print(ds2.ReadAsArray().shape)
ds2 = None
</code>```

Release the file from memory:

```<code>gdal.Unlink('/vsimem/inmem.vrt')
</code>```

I'm not entirely sure about the scope of vsimem, so if you mean another Python interpreter by 'external', it might not work.

Body:
I have a GDAL dataset that exists only in memory (inmem_ds):

In: gdal.Info(inmem_ds)
Out:
('Driver: NUMPY/Numeric Python Array\n'
 'Files: none associated\n'
 'Size is 500, 500\n'
 'Coordinate System is:\n'
 'PROJCS["WGS 84 / UTM zone 19N",\n'
 '    GEOGCS["WGS 84",\n'
 '        DATUM["WGS_1984",\n'
 '            SPHEROID["WGS 84",6378137,298.257223563,\n'
 '                AUTHORITY["EPSG","7030"]],\n'
 '            AUTHORITY["EPSG","6326"]],\n'
 '        PRIMEM["Greenwich",0,\n'
 '            AUTHORITY["EPSG","8901"]],\n'
 '        UNIT["degree",0.0174532925199433,\n'
 '            AUTHORITY["EPSG","9122"]],\n'
 '        AUTHORITY["EPSG","4326"]],\n'
 '    PROJECTION["Transverse_Mercator"],\n'
 '    PARAMETER["latitude_of_origin",0],\n'
 '    PARAMETER["central_meridian",-69],\n'
 '    PARAMETER["scale_factor",0.9996],\n'
 '    PARAMETER["false_easting",500000],\n'
 '    PARAMETER["false_northing",0],\n'
 '    UNIT["metre",1,\n'
 '        AUTHORITY["EPSG","9001"]],\n'
 '    AXIS["Easting",EAST],\n'
 '    AXIS["Northing",NORTH],\n'
 '    AUTHORITY["EPSG","32619"]]\n'
 'Origin = (617085.000000000000000,-1512585.000000000000000)\n'
 'Pixel Size = (30.000000000000000,-30.000000000000000)\n'
 'Corner Coordinates:\n'
 'Upper Left  (  617085.000,-1512585.000) ( 67d55\' 2.38"W, 13d40\'47.58"S)\n'
 'Lower Left  (  617085.000,-1527585.000) ( 67d55\' 0.13"W, 13d48\'55.77"S)\n'
 'Upper Right (  632085.000,-1512585.000) ( 67d46\'43.12"W, 13d40\'45.26"S)\n'
 'Lower Right (  632085.000,-1527585.000) ( 67d46\'40.59"W, 13d48\'53.42"S)\n'
 'Center      (  624585.000,-1520085.000) ( 67d50\'51.55"W, 13d44\'50.54"S)\n'
 'Band 1 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 2 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 3 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 4 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 5 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 6 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 7 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n'
 'Band 8 Block=500x1 Type=Int16, ColorInterp=Undefined\n'
 '  NoData Value=-9999\n')

Now I want to pass this dataset directly to an external Python library that uses gdal.Open() to open its input datasets. So I need a physical file path that I can pass to gdal.Open(). But I don´t want to write the in-memory GDAL dataset to disk in order to save IO time.

Is there any way to pass an in-memory dataset to gdal.Open()?

I tried to use a VRT dataset but it does not work:

drv = gdal.GetDriverByName("VRT")
vrt = drv.CreateCopy("/mypath/test.vrt", inmem_ds)
type(vrt.ReadAsArray()) # numpy.ndarray -> works

gdal.Open('/mypath/test.vrt') # None, last GDAL error: Exception: Error reading file:  Missing <SourceFilename> element in VRTRasterBand.

The saved VRT file (mypath/test.vrt) looks like this:

<VRTDataset rasterXSize="500" rasterYSize="500">
  <SRS>PROJCS["WGS 84 / UTM zone 19N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-69],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32619"]]</SRS>
  <GeoTransform>  6.1708500000000000e+05,  3.0000000000000000e+01,  0.0000000000000000e+00, -1.5125850000000000e+06,  0.0000000000000000e+00, -3.0000000000000000e+01</GeoTransform>
  <VRTRasterBand dataType="Int16" band="1">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>1</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="2">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>2</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="3">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>3</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="4">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>4</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="5">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>5</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="6">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>6</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="7">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>7</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
  <VRTRasterBand dataType="Int16" band="8">
    <NoDataValue>-9999</NoDataValue>
    <SimpleSource>
      <SourceFilename relativeToVRT="0"></SourceFilename>
      <SourceBand>8</SourceBand>
      <SourceProperties RasterXSize="500" RasterYSize="500" DataType="Int16" BlockXSize="500" BlockYSize="1" />
      <SrcRect xOff="0" yOff="0" xSize="500" ySize="500" />
      <DstRect xOff="0" yOff="0" xSize="500" ySize="500" />
    </SimpleSource>
  </VRTRasterBand>
</VRTDataset>

Body:
You can write the VRT to memory by using the vsimem prefix, beware that the data actually gets written to memory, so any format other then VRT can increase the memory significantly, depending on the actual filesize.

Also note that the in-memory file remains, even after closing the dataset handle. So you need to unlink it yourself when your done using it, or it will stay memory.

Therefore keep track of the in-mem locations you are using, so you can unlink them properly. Writing to an existing vsimem location, before its 'unlinked' wont work, and remain the original file. That can be a bit of a gotcha.

To output either a file on-disk, or an already open Dataset to an in-mem VRT:

ds = gdal.Translate('/vsimem/inmem.vrt', some_file_or_dataset, format='VRT')
print(ds.ReadAsArray().shape)
ds = None

Open it again:

ds2 = gdal.Open('/vsimem/inmem.vrt')
print(ds2.ReadAsArray().shape)
ds2 = None

Release the file from memory:

gdal.Unlink('/vsimem/inmem.vrt')

I'm not entirely sure about the scope of vsimem, so if you mean another Python interpreter by 'external', it might not work.


来源: stackexchange

问:
How to send a message with "\0" to a Server via TCP
I've managed to create a connection between my Program(client) and a Server.
Now I want to send the following Text "TOR\0". The Server explicit needs this Info for starting an Operation.
The problem is, that everytime I try to define the text

```<code>char a[]="TOR\0";
</code>```

My client only sends three bytes... Without the NULL at the end.

I can send 5 different Characters like {"T","O","R","\","0"}, but I know I need 4 Bytes of Data. I also know the four Bytes need to have  the information "T", "O", "R", "\0". But everytime I try sending this my cpp only sends "T", "O", "R", because it stops reading at the NULL which represents the end of line.

I also tried fixing the length in the send-function. I know I have to specify the length by sending it. But by fixing the length on 4 doesn't work. I use this to see if it worked:

```<code>Result = send( ConnectSocket, a, (int)strlen(a), 0 );
cout << Result << endl;
</code>```

How do I attache the NULL at the end of the text without causing it C++ to stop reading the message at that exact point?

答: You should be using sizeof a instead of strlen(a) if you're dealing in embedded nulls.

ContentLicense: CC BY-SA 3.0

Body:
I've managed to create a connection between my Program(client) and a Server.
Now I want to send the following Text "TOR\0". The Server explicit needs this Info for starting an Operation.
The problem is, that everytime I try to define the text

char a[]="TOR\0";

My client only sends three bytes... Without the NULL at the end.

I can send 5 different Characters like {"T","O","R","\","0"}, but I know I need 4 Bytes of Data. I also know the four Bytes need to have  the information "T", "O", "R", "\0". But everytime I try sending this my cpp only sends "T", "O", "R", because it stops reading at the NULL which represents the end of line.

I also tried fixing the length in the send-function. I know I have to specify the length by sending it. But by fixing the length on 4 doesn't work. I use this to see if it worked:

Result = send( ConnectSocket, a, (int)strlen(a), 0 );
cout << Result << endl;

How do I attache the NULL at the end of the text without causing it C++ to stop reading the message at that exact point?


问:
C# notation understanding Select(int.Parse)
I found a little script that I understand fully. I've got a string with "1 -2 5 40" for example. It reads the input string, splits it into a temporary array. Then this array is parsed and each element is transformed into an integer. The whole thing is order to give the nearest integer to zero.

But what I don't understand is the notation Select(int.Parse). There is no lambda expression here and the method int.Parse isn't called with brackets. Same with the OrderBy(Math.Abs)

Thank you in advance =)

```<code>var temps = Console.ReadLine().Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);

var result = temps.Select(int.Parse)
.OrderBy(Math.Abs)
.ThenByDescending(x => x)
.FirstOrDefault();
</code>```

答:
The parameter for .Select() is Func<T1, T2>() where T1 is the input parameter (the individual values of temps), and T2 is the return type.

Typically, this is written as a lambda function: x => return x + 1, etc. However, any method that fits the generic definitions can be used without having to be written as a lambda since the method name is the same as assigning the lambda to a variable.

So Func<string, int> parseInt = s => Convert.ToInt32(s); is syntactically equivalent to calling the method int.Parse(s).

The language creates the shortcut of automatically passing the Func parameter to the inside method to create more readable code.

Body:
I found a little script that I understand fully. I've got a string with "1 -2 5 40" for example. It reads the input string, splits it into a temporary array. Then this array is parsed and each element is transformed into an integer. The whole thing is order to give the nearest integer to zero.

But what I don't understand is the notation Select(int.Parse). There is no lambda expression here and the method int.Parse isn't called with brackets. Same with the OrderBy(Math.Abs)

Thank you in advance =)

var temps = Console.ReadLine().Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);

var result = temps.Select(int.Parse)
.OrderBy(Math.Abs)
.ThenByDescending(x => x)
.FirstOrDefault();


问:
Search on Welcome Controller
I have a Product (imovel) controller where the users can create his own Products (imovels). I am using devise for the authentication and the CRUD (create, Update, Delete) needs login. So for the clients be able to see the products and doesn't need a user, I created the Welcome controller where so it is the root.

In the Index of the Products I use Ransack to do the research in the table and works just fine. (very happy about it).

On the welcome controller I try to do the same thing, but when I submit the search the page gets redirect to the imovels#index.

Controller:

```<code>class WelcomeController < ApplicationController
  def index
    @q = Imovel.ransack(params[:q])
    @imovel = @q.result(distinct: true)
  end
end
</code>```

View:

```<code><div class="container text-center">
  <%= search_form_for @q do |f| %>
      # Search if the name field contains...
      <%= f.label :descricao_cont %>
      <%= f.search_field :descricao_cont %>
      <%= f.submit "Pesquisar", class: "btn btn-primary" %>
  <% end %>
</div>
</code>```

Another thing that can be important in the index (imovels#index) there is a for in a tr and the information is filtered there:

Imovels Index

```<code><tbody>
      <% @imovels.each do |imovel| %>
      <tr>
            <td><%= imovel.id %></td>
            <td><%= imovel.descricao %></td>
<% end %>
</code>```

And in the welcome controller where I need the search, I used Divs:

Welcome Index

```<code><% @imovels.each do |imovel| %>
  <div class="card">
    <div class="containerImovel">
      <h4><b><%= imovel.descricao %></b></h4>
      <p><%= imovel.cidade %> - <%= imovel.bairro.nome %> </p>
 </div>
  </div>
<% end %>
</code>```

How can I do the search on the divs of welcome controller? Ransack is the better option for it? It is possible to search in the has_many :through association?

答:
Add a path for it in your routes.rb

```<code>resources :imovel do
  collection do
    match 'search' => 'welcome#search', via: [:get, :post], as: :search
  end
end
</code>```

and then add a new controller action to WelcomeController

```<code>def search
  index
  render :index
end
</code>```

and afterwards modify the search form like so

```<code><%= search_form_for @q, url: search_imovel_path, html: { method: :post } do |f| %>
</code>```

Be sure to recheck the naming/variables as I'm not completely familiar with your app

Title: Search on Welcome Controller

Body:
I have a Product (imovel) controller where the users can create his own Products (imovels). I am using devise for the authentication and the CRUD (create, Update, Delete) needs login. So for the clients be able to see the products and doesn't need a user, I created the Welcome controller where so it is the root.

In the Index of the Products I use Ransack to do the research in the table and works just fine. (very happy about it).

On the welcome controller I try to do the same thing, but when I submit the search the page gets redirect to the imovels#index.

Controller:

class WelcomeController < ApplicationController
  def index
    @q = Imovel.ransack(params[:q])
    @imovel = @q.result(distinct: true)
  end
end

View:

  <%= search_form_for @q do |f| %>
      # Search if the name field contains...
      <%= f.label :descricao_cont %>
      <%= f.search_field :descricao_cont %>
      <%= f.submit "Pesquisar", class: "btn btn-primary" %>
  <% end %>

Another thing that can be important in the index (imovels#index) there is a for in a tr and the information is filtered there:

Imovels Index

      <% @imovels.each do |imovel| %>

            <%= imovel.id %>
            <%= imovel.descricao %>
<% end %>

And in the welcome controller where I need the search, I used Divs:

Welcome Index

<% @imovels.each do |imovel| %>

<%= imovel.descricao %>

<%= imovel.cidade %> - <%= imovel.bairro.nome %>

<% end %>

How can I do the search on the divs of welcome controller? Ransack is the better option for it? It is possible to search in the has_many :through association?

Body:
Add a path for it in your routes.rb

resources :imovel do
  collection do
    match 'search' => 'welcome#search', via: [:get, :post], as: :search
  end
end

and then add a new controller action to WelcomeController

def search
  index
  render :index
end

and afterwards modify the search form like so

<%= search_form_for @q, url: search_imovel_path, html: { method: :post } do |f| %>

Be sure to recheck the naming/variables as I'm not completely familiar with your app


问:
How to prevent users from accessing .pdf files untill they are not being redirect from any page of website by using .htaccess?
How can I prevent users from accessing .pdf file directly from url?

I've a page that contains several  with .pdf href.
And I want that if someone click on these links then it should be go to the relative path and open the document. but If someone trying to copy and paste link in other tab then document shouldn't be open.

Please help me.

答:
Issue resolved.
Thanks for your precious time.
Here is my code that I'm using in my .htaccess file.

```<code>RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/ [NC]
RewriteCond %{REQUEST_URI} !hotlink\.(gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx|mp4|mov) [NC]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
RewriteRule .*\.(gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx|mp4|mov)$ http://example.com/ [NC]
</code>```

Hope now you all understand that what I wanted to do.

Body:
Issue resolved.
Thanks for your precious time.
Here is my code that I'm using in my .htaccess file.

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/ [NC]
RewriteCond %{REQUEST_URI} !hotlink\.(gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx|mp4|mov) [NC]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
RewriteRule .*\.(gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx|mp4|mov)$ http://example.com/ [NC]

Hope now you all understand that what I wanted to do.


问:
Helper in order to copy non null properties from object to another
See the following class

```<code>public class Parent {

    private String name;
    private int age;
    private Date birthDate;

    // getters and setters

}
</code>```

Suppose I have created a parent object as follows

```<code>Parent parent = new Parent();

parent.setName("A meaningful name");
parent.setAge(20);
</code>```

Notice according to code above birthDate property is null. Now I want to copy only non-null properties from parent object to another. Something like

```<code>SomeHelper.copyNonNullProperties(parent, anotherParent);
</code>```

I need it because I want to update anotherParent object without overwriting its non-null with null values.

Do you know some helper like this one?

I accept minimal code as answer whether no helper in mind

答:
Using PropertyUtils (commons-beanutils)

```<code>for (Map.Entry<String, Object> e : PropertyUtils.describe(parent).entrySet()) {
         if (e.getValue() != null && !e.getKey().equals("class")) {
                PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue());
         }
}
</code>```

in Java8:

```<code>    PropertyUtils.describe(parent).entrySet().stream()
        .filter(e -> e.getValue() != null)
        .filter(e -> ! e.getKey().equals("class"))
        .forEach(e -> {
        try {
            PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue());
        } catch (Exception e) {
            // Error setting property ...;
        }
    });
</code>```

ContentLicense: CC BY-SA 4.0

Body:
See the following class

public class Parent {

    private String name;
    private int age;
    private Date birthDate;

    // getters and setters

}

Suppose I have created a parent object as follows

Parent parent = new Parent();

parent.setName("A meaningful name");
parent.setAge(20);

Notice according to code above birthDate property is null. Now I want to copy only non-null properties from parent object to another. Something like

SomeHelper.copyNonNullProperties(parent, anotherParent);

I need it because I want to update anotherParent object without overwriting its non-null with null values.

Do you know some helper like this one?

I accept minimal code as answer whether no helper in mind

Body:
Using PropertyUtils (commons-beanutils)

for (Map.Entry<String, Object> e : PropertyUtils.describe(parent).entrySet()) {
         if (e.getValue() != null && !e.getKey().equals("class")) {
                PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue());
         }
}

in Java8:

    PropertyUtils.describe(parent).entrySet().stream()
        .filter(e -> e.getValue() != null)
        .filter(e -> ! e.getKey().equals("class"))
        .forEach(e -> {
        try {
            PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue());
        } catch (Exception e) {
            // Error setting property ...;
        }
    });


问:
Data validation for each cell to check whether the value is available or not using EPplus
I am using Epplus for uploading file.I have two sheet in .xlsx format.I want to ensure that each and every cell has value.For example in my excel i have dropdown box.If a user have details in first sheet and second sheet is empty.But this empty sheet have only one value which is added in sheet by mistake by use of this dropdown.So at this stage it will show object null reference error when it goes in to this loop

```<code>    for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
     {

         if (int.TryParse(s.Cells[rowIterator, 1].Value.ToString(), out n) && int.TryParse(s.Cells[rowIterator, 2].Value.ToString(), out n))
        {
          Pss.Pbr = Convert.ToInt32(s.Cells[rowIterator, 1].Value);
          Pss.Amount = Convert.ToInt32(s.Cells[rowIterator, 2].Value);
         Ps.Add(Pss);

        }
}
</code>```

how to validate that all columns and row have values

答:
In the loop, check if the cell is not null and is not empty, like this:

```<code>bool allRangeHasValue=true;
for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
{
    for(int col =1;col<=s.Dimension.End.Column;col++)
    {

      if(String.IsNullOrWhiteSpace(s.Cells[rowIterator, col]?.Value?.ToString())
      {
          allRangeHasValue=false;
          break;
      }
    }
    if(!allRangeHasValue)
    {
      break;
    }
}
</code>```

Edit:
Based on your comment, you could do something like:
Edit2: Since you're using TryParse, you don't need to parse again, TryParse returns the value in the out variable.

```<code>for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
 {
     int n1;
     int n2;
     if (!string.IsNullOrWhiteSpace(s.Cells[rowIterator, 1]?.Value?.ToString()) &&
         !string.IsNullOrWhiteSpace(s.Cells[rowIterator, 2]?.Value?.ToString()) &&
         int.TryParse(s.Cells[rowIterator, 1].Value.ToString(), out n1) &&
         int.TryParse(s.Cells[rowIterator, 2].Value.ToString(), out n2))
    {
      Pss.Pbr = n1;
      Pss.Amount = n2;
      Ps.Add(Pss);

    }
}
</code>```

Body:
I am using Epplus for uploading file.I have two sheet in .xlsx format.I want to ensure that each and every cell has value.For example in my excel i have dropdown box.If a user have details in first sheet and second sheet is empty.But this empty sheet have only one value which is added in sheet by mistake by use of this dropdown.So at this stage it will show object null reference error when it goes in to this loop

    for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
     {

         if (int.TryParse(s.Cells[rowIterator, 1].Value.ToString(), out n) && int.TryParse(s.Cells[rowIterator, 2].Value.ToString(), out n))
        {
          Pss.Pbr = Convert.ToInt32(s.Cells[rowIterator, 1].Value);
          Pss.Amount = Convert.ToInt32(s.Cells[rowIterator, 2].Value);
         Ps.Add(Pss);

        }
}

how to validate that all columns and row have values

Body:
In the loop, check if the cell is not null and is not empty, like this:

bool allRangeHasValue=true;
for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
{
    for(int col =1;col<=s.Dimension.End.Column;col++)
    {

      if(String.IsNullOrWhiteSpace(s.Cells[rowIterator, col]?.Value?.ToString())
      {
          allRangeHasValue=false;
          break;
      }
    }
    if(!allRangeHasValue)
    {
      break;
    }
}

Edit:
Based on your comment, you could do something like:
Edit2: Since you're using TryParse, you don't need to parse again, TryParse returns the value in the out variable.

for (int rowIterator = 2; rowIterator <= noOfRow; rowIterator++)
 {
     int n1;
     int n2;
     if (!string.IsNullOrWhiteSpace(s.Cells[rowIterator, 1]?.Value?.ToString()) &&
         !string.IsNullOrWhiteSpace(s.Cells[rowIterator, 2]?.Value?.ToString()) &&
         int.TryParse(s.Cells[rowIterator, 1].Value.ToString(), out n1) &&
         int.TryParse(s.Cells[rowIterator, 2].Value.ToString(), out n2))
    {
      Pss.Pbr = n1;
      Pss.Amount = n2;
      Ps.Add(Pss);

    }
}


问:
DecimalFormat java allow to type 0 after dot
I have a DecimalFormat with the following pattern "#,###.###"
But when I want to type for example 50.05 it does not allow to, as I parse the string to number every time a text changes and when I call

```<code>df.parse("50.0");
</code>```

it returns 50. and cuts the 0

Any ideas what can I do to be able to type numbers like 50.05 ?

The full code of my class is presented below. Sorry if it is too verbose:

```<code>private class NumberTextWatcher implements TextWatcher {
    @SuppressWarnings("unused")
    private static final String TAG = "NumberTextWatcher";

    private DecimalFormat df;
    private DecimalFormat dfnd;
    private boolean hasFractionalPart;

    private EditText et;

    NumberTextWatcher(EditText et) {
        df = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
        df.applyLocalizedPattern(hasThousandSeparator ? "#,###.###" : "####.###");
        df.setDecimalSeparatorAlwaysShown(true);
        df.setMaximumFractionDigits(maxDecimal);
        dfnd = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
        dfnd.applyLocalizedPattern(hasThousandSeparator ? "#,###" : "####");
        dfnd.setMaximumFractionDigits(maxDecimal);
        this.et = et;
        hasFractionalPart = false;
    }

    @Override
    public void afterTextChanged(Editable s) {
        et.removeTextChangedListener(this);

        try {
            int inilen, endlen;
            inilen = et.getText().length();

            String sign = hasSign ? s.toString().startsWith("-") ? "-" : "+" : null;
            String sStr = hasSignAttached(s) ? s.toString().substring(1) : s.toString();

            String v = sStr.replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");

            if(v.length() == 0){
                return;
            }

            if(hasFractionalPart){
                String[] vSplit = v.split("\\.");

                String intStr = vSplit[0];
                String decStr = vSplit.length > 1 ? vSplit[1] : "";

                if(intStr.length() > maxNumbers)
                    intStr = intStr.substring(0, maxNumbers);

                if(decStr.length() > maxDecimal)
                    decStr = decStr.substring(0, maxDecimal);

                v = String.format("%s.%s", intStr, decStr);
            } else {
                if(v.length() > maxNumbers)
                    v = v.substring(0, maxNumbers);
            }

            Number n = df.parse(v);
            int cp = et.getSelectionStart();

            String formatted;

            if (hasFractionalPart) {
                formatted = df.format(n);
            } else {
                formatted = dfnd.format(n);
            }

            et.setText(hasSign ? String.format("%s%s", sign, formatted) : formatted);

            endlen = et.getText().length();
            int sel = (cp + (endlen - inilen));
            if (sel > 0 && sel <= et.getText().length()) {
                et.setSelection(sel);
            } else {
                // place cursor at the end?
                et.setSelection(et.getText().length() - 1);
            }

        } catch (Exception e) {
            ExceptionTracker.trackException(e);
        } finally {
            et.addTextChangedListener(this);
        }
    }

    private boolean hasSignAttached(Editable s){
        return s.toString().startsWith("+") || s.toString().startsWith("-");
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if(hasSign && start == 1 && count == 1){
            et.setText("");
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        hasFractionalPart = s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator()));
    }
}
</code>```

答:
this code solves the problem:</p>

```<code>import java.text.DecimalFormat;

public class DecimalFormatExample {

    public static void main(String[] args) {

    DecimalFormat dformat = new DecimalFormat("#,###.###");
    dformat.setMinimumFractionDigits(1);

    String someNumber = "50.05";
    Double someNumberDouble = Double.valueOf(someNumber);
    System.out.println(dformat.format(someNumberDouble));  // 50.05

    someNumber = "50.0";
    someNumberDouble = Double.valueOf(someNumber);
    System.out.println(dformat.format(someNumberDouble));  // 50.0

    }
}
</code>```

Body:
I have a DecimalFormat with the following pattern "#,###.###"
But when I want to type for example 50.05 it does not allow to, as I parse the string to number every time a text changes and when I call

df.parse("50.0");

it returns 50. and cuts the 0

Any ideas what can I do to be able to type numbers like 50.05 ?

The full code of my class is presented below. Sorry if it is too verbose:

private class NumberTextWatcher implements TextWatcher {
    @SuppressWarnings("unused")
    private static final String TAG = "NumberTextWatcher";

    private DecimalFormat df;
    private DecimalFormat dfnd;
    private boolean hasFractionalPart;

    private EditText et;

    NumberTextWatcher(EditText et) {
        df = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
        df.applyLocalizedPattern(hasThousandSeparator ? "#,###.###" : "####.###");
        df.setDecimalSeparatorAlwaysShown(true);
        df.setMaximumFractionDigits(maxDecimal);
        dfnd = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH);
        dfnd.applyLocalizedPattern(hasThousandSeparator ? "#,###" : "####");
        dfnd.setMaximumFractionDigits(maxDecimal);
        this.et = et;
        hasFractionalPart = false;
    }

    @Override
    public void afterTextChanged(Editable s) {
        et.removeTextChangedListener(this);

        try {
            int inilen, endlen;
            inilen = et.getText().length();

            String sign = hasSign ? s.toString().startsWith("-") ? "-" : "+" : null;
            String sStr = hasSignAttached(s) ? s.toString().substring(1) : s.toString();

            String v = sStr.replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");

            if(v.length() == 0){
                return;
            }

            if(hasFractionalPart){
                String[] vSplit = v.split("\\.");

                String intStr = vSplit[0];
                String decStr = vSplit.length > 1 ? vSplit[1] : "";

                if(intStr.length() > maxNumbers)
                    intStr = intStr.substring(0, maxNumbers);

                if(decStr.length() > maxDecimal)
                    decStr = decStr.substring(0, maxDecimal);

                v = String.format("%s.%s", intStr, decStr);
            } else {
                if(v.length() > maxNumbers)
                    v = v.substring(0, maxNumbers);
            }

            Number n = df.parse(v);
            int cp = et.getSelectionStart();

            String formatted;

            if (hasFractionalPart) {
                formatted = df.format(n);
            } else {
                formatted = dfnd.format(n);
            }

            et.setText(hasSign ? String.format("%s%s", sign, formatted) : formatted);

            endlen = et.getText().length();
            int sel = (cp + (endlen - inilen));
            if (sel > 0 && sel <= et.getText().length()) {
                et.setSelection(sel);
            } else {
                // place cursor at the end?
                et.setSelection(et.getText().length() - 1);
            }

        } catch (Exception e) {
            ExceptionTracker.trackException(e);
        } finally {
            et.addTextChangedListener(this);
        }
    }

    private boolean hasSignAttached(Editable s){
        return s.toString().startsWith("+") || s.toString().startsWith("-");
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if(hasSign && start == 1 && count == 1){
            et.setText("");
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        hasFractionalPart = s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator()));
    }
}

Body:
this code solves the problem:

import java.text.DecimalFormat;

public class DecimalFormatExample {

    public static void main(String[] args) {

    DecimalFormat dformat = new DecimalFormat("#,###.###");
    dformat.setMinimumFractionDigits(1);

    String someNumber = "50.05";
    Double someNumberDouble = Double.valueOf(someNumber);
    System.out.println(dformat.format(someNumberDouble));  // 50.05

    someNumber = "50.0";
    someNumberDouble = Double.valueOf(someNumber);
    System.out.println(dformat.format(someNumberDouble));  // 50.0

    }
}


问:
Cross-domain AJAX request behaving oddly on Android phone's native browser
My setup is like so:

An SQLite database sits in one of my Apache folders

A Perl cgi script sits in the same folder, with public permissions, so that it can handle database interactions

A C program, running on the same machine, listens on a specific port for specific JSON requests and responds with specifically-formatted JSON data

A webpage, written primarily in jQuery and HTML, must access both the SQLite database and the C program somewhat constantly. It does so using AJAX requests -- here's an example from the code:

```<code>function sendCommand(cmd, callback) {
$.ajax({url: "http://192.168.42.90:6112/?cmd=" + cmd,
    dataType: "jsonp",
    success: function(d,s,x) {
          callback(d);
    },
    jsonpCallback: "json",
    error: function(xhr) {
         alert('Error: ' + xhr.status);
    }
});
}
</code>```

So I might invoke it with something like sendCommand("get_x", updatePosition) -- so that it'd send the get_x command along to the C program, and, if it got good feedback, run said feedback through the updatePosition function.

So all of this works SPLENDIDLY if I'm running on a webpage on the same machine. If I move to another machine -- in this case, specifically, an Android phone, doing tethered IP over USB, it ... sort of works. This is what's puzzling me -- it doesn't silently fail, like I'm used to JavaScript doing. Instead, as far as I can tell, it sends the request out, claims that it got data back, and runs the callback function -- only, according to the C program, nothing ever happened; according to Wireshark, no packets were sent; and the "data" that it gets back is an empty, specially-formatted string. If I'm expecting "(5,5)" as output from C, it's getting "(0,0)" -- why is it getting anything at all? Much less filling "(,)" with 0s?

Very strange. I've tried various little things, like changing the dataType to "json", making sure all my permissions are set up right, etc. I'm fairly sure that Apache isn't interfering, since there's nothing in the logs -- what gets me is that I don't see anything on Wireshark, of all things. It's like the phone just plain isn't trying to make the request.

答:
Have you checked the console in firebug or a JS debugger? I ran into the issue that jquery prevents you from doing AJAX calls in this manner due to security issues and will return this error

```<code>Access to restricted URI denied" code: "1012
</code>```

However, it looks like some people have attempted work arounds.  Give this a read through if you haven't already http://usejquery.com/posts/9/the-jquery-cross-domain-ajax-guide

ContentLicense: CC BY-SA 2.5

Body:
My setup is like so:

An SQLite database sits in one of my Apache folders

A Perl cgi script sits in the same folder, with public permissions, so that it can handle database interactions

A C program, running on the same machine, listens on a specific port for specific JSON requests and responds with specifically-formatted JSON data

A webpage, written primarily in jQuery and HTML, must access both the SQLite database and the C program somewhat constantly. It does so using AJAX requests -- here's an example from the code:

function sendCommand(cmd, callback) {
$.ajax({url: "http://192.168.42.90:6112/?cmd=" + cmd,
    dataType: "jsonp",
    success: function(d,s,x) {
          callback(d);
    },
    jsonpCallback: "json",
    error: function(xhr) {
         alert('Error: ' + xhr.status);
    }
});
}

So I might invoke it with something like sendCommand("get_x", updatePosition) -- so that it'd send the get_x command along to the C program, and, if it got good feedback, run said feedback through the updatePosition function.

So all of this works SPLENDIDLY if I'm running on a webpage on the same machine. If I move to another machine -- in this case, specifically, an Android phone, doing tethered IP over USB, it ... sort of works. This is what's puzzling me -- it doesn't silently fail, like I'm used to JavaScript doing. Instead, as far as I can tell, it sends the request out, claims that it got data back, and runs the callback function -- only, according to the C program, nothing ever happened; according to Wireshark, no packets were sent; and the "data" that it gets back is an empty, specially-formatted string. If I'm expecting "(5,5)" as output from C, it's getting "(0,0)" -- why is it getting anything at all? Much less filling "(,)" with 0s?

Very strange. I've tried various little things, like changing the dataType to "json", making sure all my permissions are set up right, etc. I'm fairly sure that Apache isn't interfering, since there's nothing in the logs -- what gets me is that I don't see anything on Wireshark, of all things. It's like the phone just plain isn't trying to make the request.

Body:
Have you checked the console in firebug or a JS debugger? I ran into the issue that jquery prevents you from doing AJAX calls in this manner due to security issues and will return this error

Access to restricted URI denied" code: "1012

However, it looks like some people have attempted work arounds.  Give this a read through if you haven't already http://usejquery.com/posts/9/the-jquery-cross-domain-ajax-guide


问:
Laravel 5.4 set and increment custom session variable
Im new to Laravel. Im trying to set a counter of failed login attempts by using sessions. However I not able to make it work. Here is my UserController handling registration, login and logout. I wanna have a global variable, which I can access from the login form and force user to use CAPTCHA if there is more than 2 failed logins

```<code>public function postSignIn(Request $request)
{
   $failedAttempt = Session::get('FailedAttempts');
   if(!isset($failedAttempt)) $failedAttempt = 0;

    $this->validate($request, [
        'email' => 'required',
        'password' => 'required'
    ]);
    if (Auth::attempt(['email' => $request['email'], 'password' =>
           $request['password'], 'active' => 1])) {
        return redirect()->route('dashboard');
    } else {
        $failedAttempt++;
        Session::put('FailedAttempts', $failedAttempt);
        dd("Counter: " . $failedAttempt); //<- Always 1!!!
    }
</code>```

$failedAttempt never gets incremented on the next failed login attempts. I've tried Session::set('FailedAttempts', $failedAttempt);, session(['FailedAttempts' => $failedAttempt]); but still no luck

答:
the secret of non persisting session I still don't know, but my solution was to use Session::save():

```<code>Session::put('FailedAttempts', $failedAttempt);
Session::save();
</code>```

I found my answer here: https://laracasts.com/discuss/channels/general-discussion/l5-sessions-dont-persist

Some people blame Nginx+php-fpm for that

Body:
Im new to Laravel. Im trying to set a counter of failed login attempts by using sessions. However I not able to make it work. Here is my UserController handling registration, login and logout. I wanna have a global variable, which I can access from the login form and force user to use CAPTCHA if there is more than 2 failed logins

public function postSignIn(Request $request)
{
   $failedAttempt = Session::get('FailedAttempts');
   if(!isset($failedAttempt)) $failedAttempt = 0;

    $this->validate($request, [
        'email' => 'required',
        'password' => 'required'
    ]);
    if (Auth::attempt(['email' => $request['email'], 'password' =>
           $request['password'], 'active' => 1])) {
        return redirect()->route('dashboard');
    } else {
        $failedAttempt++;
        Session::put('FailedAttempts', $failedAttempt);
        dd("Counter: " . $failedAttempt); //<- Always 1!!!
    }

$failedAttempt never gets incremented on the next failed login attempts. I've tried Session::set('FailedAttempts', $failedAttempt);, session(['FailedAttempts' => $failedAttempt]); but still no luck

Body:
the secret of non persisting session I still don't know, but my solution was to use Session::save():

Session::put('FailedAttempts', $failedAttempt);
Session::save();

I found my answer here: https://laracasts.com/discuss/channels/general-discussion/l5-sessions-dont-persist

Some people blame Nginx+php-fpm for that


问:
How to print if first condition is not met?
I'm practicing conditionals and logical operators.

How do I make the following rock, paper, scissors game print "This is not a valid object selection." immediately after Player 1's input, if Player 1 enters an invalid object? Right now the string is not printed until both players have entered an object.

Also, any suggestions for making the following code more elegant?

```<code>player1 = input('Player 1? ')
player2 = input('Player 2? ')

if (player1.lower() == 'rock' and
    player2.lower() == 'rock'):
    print('Tie.')
elif (player1.lower() == 'rock' and
    player2.lower() == 'paper'):
    print('Player 2 wins.')
elif (player1.lower() == 'rock' and
    player2.lower() == 'scissors'):
    print('Player 1 wins.')
elif (player1.lower() == 'paper' and
    player2.lower() == 'paper'):
    print('Tie.')
elif (player1.lower() == 'paper' and
    player2.lower() == 'scissors'):
    print('Player 2 wins.')
elif (player1.lower() == 'paper' and
    player2.lower() == 'rock'):
    print('Player 1 wins.')
elif (player1.lower() == 'scissors' and
    player2.lower() == 'scissors'):
    print('Tie.')
elif (player1.lower() == 'scissors' and
    player2.lower() == 'rock'):
    print('Player 2 wins.')
elif (player1.lower() == 'scissors' and
    player2.lower() == 'paper'):
    print('Player 1 wins.')
else:
    print('This is not a valid object selection.')
</code>```

答:
How about a function to ask each player their choice? Only if the player enters a valid selection will they be allowed to proceed through the code to your logic statements.

```<code>def get_choice(Player_number):
    print('Player', Player_number, 'please enter your choice: ', end='')
    while True:
        choice = input().lower()        #lower converts input to all lowercase
        if choice in ('rock', 'paper', 'scissors'):   # check if valid choice
            return choice   # if valid return choice
        else:
            print('Incorrect choice, try again: ', end='')  # else print this and start loop agan

player1 = get_choice('1')
player2 = get_choice('2')
</code>```

For the logic part, note that if player1 choice == player 2 choice, this will substitute 3 elif blocks in your code, ie.

```<code>if player1 == player2:
    print('tie')
</code>```

Now replaces pl==rock and p2 == rock, p1 == scissors and p2 == scissors, ect.

edit:

1) The problem if you move the print statement in 2 to inside the input in 4 is you can no longer specify the ,end='' parameter, as it does not work with input. As you said it will generate SyntaxError. The code looks much cleaner when run this way in terminal as it all lines up, but do test it for yourself.

2) end='' prints an empty string at the end of the print statement. you are confusing this with end='\n' which prints a new line after print. As my way keeps the cursor on the same line after the print, it lines up with the input to make it look nice, see above question. Note the print statement in python by default passes , end='\n'. This is why

```<code>print('hello')    #same as print('hello', end='\n')
print('world)
hello
world

print('hello', end='')
print('world', end='')
helloworld
</code>```

3) The while True loop will alway evaluate to true. So the body of the while loop will constantly cycle - However, it can return out of the entire function with the 'return choice' function. The only way to leave this function if to get down the logical steps required to reach the return statement. In this case unless the choice is in that tuple('rock', 'paper', 'scisors') it will just print invalid entry try again, finishing the block. However, As while is still true the loop will begin again and ask the user to input again. This will repeat until a valid choice is selected.

4) You could concatenate it onto the player_number eg..

```<code>print('Player', Player_number + ',' , 'please enter your choice: ', end='')
</code>```

Body:
I'm practicing conditionals and logical operators.

How do I make the following rock, paper, scissors game print "This is not a valid object selection." immediately after Player 1's input, if Player 1 enters an invalid object? Right now the string is not printed until both players have entered an object.

Also, any suggestions for making the following code more elegant?

player1 = input('Player 1? ')
player2 = input('Player 2? ')

if (player1.lower() == 'rock' and
    player2.lower() == 'rock'):
    print('Tie.')
elif (player1.lower() == 'rock' and
    player2.lower() == 'paper'):
    print('Player 2 wins.')
elif (player1.lower() == 'rock' and
    player2.lower() == 'scissors'):
    print('Player 1 wins.')
elif (player1.lower() == 'paper' and
    player2.lower() == 'paper'):
    print('Tie.')
elif (player1.lower() == 'paper' and
    player2.lower() == 'scissors'):
    print('Player 2 wins.')
elif (player1.lower() == 'paper' and
    player2.lower() == 'rock'):
    print('Player 1 wins.')
elif (player1.lower() == 'scissors' and
    player2.lower() == 'scissors'):
    print('Tie.')
elif (player1.lower() == 'scissors' and
    player2.lower() == 'rock'):
    print('Player 2 wins.')
elif (player1.lower() == 'scissors' and
    player2.lower() == 'paper'):
    print('Player 1 wins.')
else:
    print('This is not a valid object selection.')

Body:
How about a function to ask each player their choice? Only if the player enters a valid selection will they be allowed to proceed through the code to your logic statements.

def get_choice(Player_number):
    print('Player', Player_number, 'please enter your choice: ', end='')
    while True:
        choice = input().lower()        #lower converts input to all lowercase
        if choice in ('rock', 'paper', 'scissors'):   # check if valid choice
            return choice   # if valid return choice
        else:
            print('Incorrect choice, try again: ', end='')  # else print this and start loop agan

player1 = get_choice('1')
player2 = get_choice('2')

For the logic part, note that if player1 choice == player 2 choice, this will substitute 3 elif blocks in your code, ie.

if player1 == player2:
    print('tie')

Now replaces pl==rock and p2 == rock, p1 == scissors and p2 == scissors, ect.

edit:

1) The problem if you move the print statement in 2 to inside the input in 4 is you can no longer specify the ,end='' parameter, as it does not work with input. As you said it will generate SyntaxError. The code looks much cleaner when run this way in terminal as it all lines up, but do test it for yourself.

2) end='' prints an empty string at the end of the print statement. you are confusing this with end='\n' which prints a new line after print. As my way keeps the cursor on the same line after the print, it lines up with the input to make it look nice, see above question. Note the print statement in python by default passes , end='\n'. This is why

print('hello')    #same as print('hello', end='\n')
print('world)
hello
world

print('hello', end='')
print('world', end='')
helloworld

3) The while True loop will alway evaluate to true. So the body of the while loop will constantly cycle - However, it can return out of the entire function with the 'return choice' function. The only way to leave this function if to get down the logical steps required to reach the return statement. In this case unless the choice is in that tuple('rock', 'paper', 'scisors') it will just print invalid entry try again, finishing the block. However, As while is still true the loop will begin again and ask the user to input again. This will repeat until a valid choice is selected.

4) You could concatenate it onto the player_number eg..

print('Player', Player_number + ',' , 'please enter your choice: ', end='')


问:
Calculate mean value for each row with interval
i need to calculate the mean value for each row (mean of interval). Here is a basic example (maybe anyone has even better idea to do it):

```<code>M_1_mb <-  (15 : -15)#creating a vector value --> small
M_31 <-  cut(M_31_mb,128)# getting 128 groups from the small vector
#M_1_mb <-  (1500 : -1500)#creating a vector value
#M_1 <-  cut(M_1_mb,128)# getting 128 groups from the vector
</code>```

I do need to get the mean value for each row/group out of 128 intervals created in M_1 (actually i do not need even those intervals, i just need the mean of them) and i cannot figure out how to do it...

I had a look at the cut2 function from Hmisc library but unfortunatelly there is no option to set up number of intervals into which vector is to be cut (-> but there is an option to get the mean value of created intervals: levels.mean...)

I would appreciate any help! Thanks!

Additional Info:

cut2 function is working well for bigger vectors (M_1_mb), however when my vector is small (M_31_mb), then i am getting a Warning message:

```<code>Warning message:
In min(xx[xx > upper]) : no non-missing arguments to min; returning Inf
</code>```

and only 31 groups are created:

```<code>M_31_mb <-  (15 : -15) # smaller vector
M_31 <-  table(cut2(M_31_mb,g=128,levels.mean = TRUE))
</code>```

whereas

g = number of quantile groups

Body:
i need to calculate the mean value for each row (mean of interval). Here is a basic example (maybe anyone has even better idea to do it):

M_1_mb <-  (15 : -15)#creating a vector value --> small
M_31 <-  cut(M_31_mb,128)# getting 128 groups from the small vector
#M_1_mb <-  (1500 : -1500)#creating a vector value
#M_1 <-  cut(M_1_mb,128)# getting 128 groups from the vector

I do need to get the mean value for each row/group out of 128 intervals created in M_1 (actually i do not need even those intervals, i just need the mean of them) and i cannot figure out how to do it...

I had a look at the cut2 function from Hmisc library but unfortunatelly there is no option to set up number of intervals into which vector is to be cut (-> but there is an option to get the mean value of created intervals: levels.mean...)

I would appreciate any help! Thanks!

Additional Info:

cut2 function is working well for bigger vectors (M_1_mb), however when my vector is small (M_31_mb), then i am getting a Warning message:

Warning message:
In min(xx[xx > upper]) : no non-missing arguments to min; returning Inf

and only 31 groups are created:

M_31_mb <-  (15 : -15) # smaller vector
M_31 <-  table(cut2(M_31_mb,g=128,levels.mean = TRUE))

whereas

g = number of quantile groups

Body:
like this?

aggregate(M_1_mb,by=list(M_1),mean)

EDIT: Result

                   Group.1       x
1    (-1.5e+03,-1.48e+03] -1488.5
2   (-1.48e+03,-1.45e+03] -1465.0
3   (-1.45e+03,-1.43e+03] -1441.5
4   (-1.43e+03,-1.41e+03] -1418.0
5   (-1.41e+03,-1.38e+03] -1394.5
6   (-1.38e+03,-1.36e+03] -1371.0
7   (-1.36e+03,-1.34e+03] -1347.5
8   (-1.34e+03,-1.31e+03] -1324.0
9   (-1.31e+03,-1.29e+03] -1301.0
10  (-1.29e+03,-1.27e+03] -1277.5
11  (-1.27e+03,-1.24e+03] -1254.0
12  (-1.24e+03,-1.22e+03] -1230.5
13   (-1.22e+03,-1.2e+03] -1207.0
14   (-1.2e+03,-1.17e+03] -1183.5
15  (-1.17e+03,-1.15e+03] -1160.0
16  (-1.15e+03,-1.12e+03] -1136.5
17   (-1.12e+03,-1.1e+03] -1113.0
18   (-1.1e+03,-1.08e+03] -1090.0
19  (-1.08e+03,-1.05e+03] -1066.5
20  (-1.05e+03,-1.03e+03] -1043.0
21  (-1.03e+03,-1.01e+03] -1019.5
22       (-1.01e+03,-984]  -996.0
23            (-984,-961]  -972.5
24            (-961,-938]  -949.0
25            (-938,-914]  -926.0
26            (-914,-891]  -902.5
27            (-891,-867]  -879.0
28            (-867,-844]  -855.5
29            (-844,-820]  -832.0
30            (-820,-797]  -808.5
31            (-797,-773]  -785.0
32            (-773,-750]  -761.5
33            (-750,-727]  -738.0
34            (-727,-703]  -715.0
35            (-703,-680]  -691.5
36            (-680,-656]  -668.0
37            (-656,-633]  -644.5
38            (-633,-609]  -621.0
39            (-609,-586]  -597.5
40            (-586,-562]  -574.0
41            (-562,-539]  -551.0
42            (-539,-516]  -527.5
43            (-516,-492]  -504.0
44            (-492,-469]  -480.5
45            (-469,-445]  -457.0
46            (-445,-422]  -433.5
47            (-422,-398]  -410.0
48            (-398,-375]  -386.5
49            (-375,-352]  -363.0
50            (-352,-328]  -340.0
51            (-328,-305]  -316.5
52            (-305,-281]  -293.0
53            (-281,-258]  -269.5
54            (-258,-234]  -246.0
55            (-234,-211]  -222.5
56            (-211,-188]  -199.0
57            (-188,-164]  -176.0
58            (-164,-141]  -152.5
59            (-141,-117]  -129.0
60           (-117,-93.8]  -105.5
61          (-93.8,-70.3]   -82.0
62          (-70.3,-46.9]   -58.5
63          (-46.9,-23.4]   -35.0
64              (-23.4,0]   -11.5
65               (0,23.4]    12.0
66            (23.4,46.9]    35.0
67            (46.9,70.3]    58.5
68            (70.3,93.8]    82.0
69             (93.8,117]   105.5
70              (117,141]   129.0
71              (141,164]   152.5
72              (164,188]   176.0
73              (188,211]   199.0
74              (211,234]   222.5
75              (234,258]   246.0
76              (258,281]   269.5
77              (281,305]   293.0
78              (305,328]   316.5
79              (328,352]   340.0
80              (352,375]   363.5
81              (375,398]   387.0
82              (398,422]   410.0
83              (422,445]   433.5
84              (445,469]   457.0
85              (469,492]   480.5
86              (492,516]   504.0
87              (516,539]   527.5
88              (539,562]   551.0
89              (562,586]   574.0
90              (586,609]   597.5
91              (609,633]   621.0
92              (633,656]   644.5
93              (656,680]   668.0
94              (680,703]   691.5
95              (703,727]   715.0
96              (727,750]   738.5
97              (750,773]   762.0
98              (773,797]   785.0
99              (797,820]   808.5
100             (820,844]   832.0
101             (844,867]   855.5
102             (867,891]   879.0
103             (891,914]   902.5
104             (914,938]   926.0
105             (938,961]   949.0
106             (961,984]   972.5
107        (984,1.01e+03]   996.0
108   (1.01e+03,1.03e+03]  1019.5
109   (1.03e+03,1.05e+03]  1043.0
110   (1.05e+03,1.08e+03]  1066.5
111    (1.08e+03,1.1e+03]  1090.0
112    (1.1e+03,1.12e+03]  1113.5
113   (1.12e+03,1.15e+03]  1137.0
114   (1.15e+03,1.17e+03]  1160.0
115    (1.17e+03,1.2e+03]  1183.5
116    (1.2e+03,1.22e+03]  1207.0
117   (1.22e+03,1.24e+03]  1230.5
118   (1.24e+03,1.27e+03]  1254.0
119   (1.27e+03,1.29e+03]  1277.5
120   (1.29e+03,1.31e+03]  1301.0
121   (1.31e+03,1.34e+03]  1324.0
122   (1.34e+03,1.36e+03]  1347.5
123   (1.36e+03,1.38e+03]  1371.0
124   (1.38e+03,1.41e+03]  1394.5
125   (1.41e+03,1.43e+03]  1418.0
126   (1.43e+03,1.45e+03]  1441.5
127   (1.45e+03,1.48e+03]  1465.0
128    (1.48e+03,1.5e+03]  1488.5


问:
In SSIS Lookup transformation, what happens if I add "top 100" to the select
I have a very slow lookup transformation in my data flow. It uses a result of the following SQL Query

```<code>SELECT e.intExpenseID, [expense_detail_id]=d.intExpenseDtlID, f.*
FROM dbo.tblExpense e
JOIN tblExpenseDtl d ON d.intExpenseID = e.intExpenseID
JOIN tblExpReceiptFile f ON f.intExpenseDtlID = d.intExpenseDtlID
ORDER BY e.intExpenseID
</code>```

The problem is, this lookup alone increases the execution time from ~1min to ~12min, which is strange, as for each row there should be no more then 4-5 files. So I added top 1000 to the SELECT, my question is- will this give me the result of ( my row join from the lookup transformation ) TOP # , or will it give me a result of my row join (lookup transformation top #). If the second one, I would be grateful for any hints how I can make the lookup faster.

Just in case someone is wondering, there is a reason why I perform a lookup, instead of getting all the data at the beginning.

答:
Well, it seems that the lookup transformation works in the my row join (lookup transformation top #), which means it was a bad solution to my problem.

The solution that actually worked, was to create additional OLE DB Source, and then in place of the lookup transformation, merge join it with my previous data flow

Body:
I have a very slow lookup transformation in my data flow. It uses a result of the following SQL Query

SELECT e.intExpenseID, [expense_detail_id]=d.intExpenseDtlID, f.*
FROM dbo.tblExpense e
JOIN tblExpenseDtl d ON d.intExpenseID = e.intExpenseID
JOIN tblExpReceiptFile f ON f.intExpenseDtlID = d.intExpenseDtlID
ORDER BY e.intExpenseID

The problem is, this lookup alone increases the execution time from ~1min to ~12min, which is strange, as for each row there should be no more then 4-5 files. So I added top 1000 to the SELECT, my question is- will this give me the result of ( my row join from the lookup transformation ) TOP # , or will it give me a result of my row join (lookup transformation top #). If the second one, I would be grateful for any hints how I can make the lookup faster.

Just in case someone is wondering, there is a reason why I perform a lookup, instead of getting all the data at the beginning.


问:
X11 forwarding of a GUI app running in docker
First off: I have read the answers to similar questions on SO, but none of them worked.

IMPORTANT NOTE: The answer below is still valid, but maybe jump to the end for an alternative.

The situation:

App with GUI is running in a docker container (CentOS 7.1) under Arch Linux. (machine A)

Machine A has a monitor connected to it.

I want to access this GUI via X11 forwarding on my Arch Linux client machine. (machine B)

What works:

GUI works locally on machine A (with /tmp/.X11-unix being mounted in the Docker container).

X11 forwarding of any app running outside of docker (X11 forwarding is set up and running properly for non-docker usage).

I can even switch the user while remotely logged in, copy the .Xauthority file to the other user and X11 forwarding works as well.

Some setup info:

Docker networking is 'bridged'.

Container can reach host (firewall is open).

DISPLAY variable is set in container (to host-ip-addr:10.0 because of TCP port 6010 where sshd is listening).

Packets to X forward port (6010) are reaching the host from the container (tcpdump checked).

What does not work:

X11 forwarding of the Docker app

Errors:

X11 connection rejected because of wrong authentication.

xterm: Xt error: Can't open display: host-ip-addr:10.0

Things i tried:

starting client ssh with ssh -Y option on machine B

putting "X11ForwardTrusted yes" in ssh_config on machine B

xhost + (so allow any clients to connect) on machine B

putting Host * in ssh_config on machine B

putting X11UseLocalhost no in sshd_config on machine A (to allow non-localhost clients)

Adding the X auth token in the container with xauth add from the login user on machine A

Just copying over the .Xauthority file from a working user into the container

Making shure .Xauthority file has correct permissions and owner

How can i just disable all the X security stuff and get this working?

Or even better: How can i get it working with security?

Is there at least a way to enable extensive debugging to see where exactly the problem is?

Alternative: The first answer below shows how to effectively resolve this issue. However: I would recommend you to look into a different approach all together, namely VNC. I personally switched to a tigerVNC setup that replaces the X11 forwarding and have not looked back. The performance is just leagues above what X11 forwarding delivered for me. There might be some instances where you cannot use VNC for whatever reason, but i would try it first.

The general setup is now as follows:
-VNC server runs on machine A on the host (not inside a docker container).
-Now you just have to figure out how to get a GUI for inside a docker container (which is a much more trivial undertaking).
-If the docker container was started NOT from the VNC environment, the DISPLAY variable maybe needs ajdusting.

答:
Ok, here is the thing:

1) Log in to remote machine

2) Check which display was set with echo $DISPLAY

3) Run xauth list

4) Copy the line corresponding to your DISPLAY

5) Enter your docker container

6) xauth add <the line you copied>*

7) Set DISPLAY with export DISPLAY=<ip-to-host>:<no-of-display>

*so far so good right?

This was nothing new...however here is the twist:
The line printed by xauth list for the login user looks something like this (in my case):

```<code><hostname-of-machine>/unix:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>
</code>```

Because i use the bridged docker setup, the X forwarding port is not listening locally, because the sshd is not running in the container. Change the line above to:

```<code><ip-of-host>:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>
</code>```

In essence: Remove the /unix part.

<ip-of-host> is the IP address where the sshd is running.

Set the DISPLAY variable as above.

So the error was that the DISPLAY name in the environment variable was not the "same" as the entry in the xauth list / .Xauthority file and the client could therefor not authenticate properly.

I switched back to an untrusted X11 forwarding setting.

The X11UseLocalhost no setting in the sshd_config file however is important, because the incomming connection will come from a "different" machine (the docker container).

Body:
Ok, here is the thing:

1) Log in to remote machine

2) Check which display was set with echo $DISPLAY

3) Run xauth list

4) Copy the line corresponding to your DISPLAY

5) Enter your docker container

6) xauth add <the line you copied>*

7) Set DISPLAY with export DISPLAY=<ip-to-host>:<no-of-display>

*so far so good right?

This was nothing new...however here is the twist:
The line printed by xauth list for the login user looks something like this (in my case):

<hostname-of-machine>/unix:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>

Because i use the bridged docker setup, the X forwarding port is not listening locally, because the sshd is not running in the container. Change the line above to:

<ip-of-host>:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>

In essence: Remove the /unix part.

<ip-of-host> is the IP address where the sshd is running.

Set the DISPLAY variable as above.

So the error was that the DISPLAY name in the environment variable was not the "same" as the entry in the xauth list / .Xauthority file and the client could therefor not authenticate properly.

I switched back to an untrusted X11 forwarding setting.

The X11UseLocalhost no setting in the sshd_config file however is important, because the incomming connection will come from a "different" machine (the docker container).


问:
How to detect when a custom tableview cell goes off the screen?
In my app I have a custom tableViewCell,

I also have a View Controller with a tableView, where I display custom tableViewCells.

Is there a method (ViewController method or TableViewCell method) which fires when tableViewCell goes off the screen, I need to make some Core Data updates in it for my cell.

(I need to know the method, because I need to update Core Data value of Timer() in my tableViewCell when it goes off the screen.)

答:
You can use tableView:didEndDisplayingCell:forRowAtIndexPath: deleaget method of UITableView

```<code>func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    }
</code>```

Here please note that when you reload tableview or cell, the cell that is being removed will trigger this method. So implement additional logic inside this method to handle that situation.

Body:
You can use tableView:didEndDisplayingCell:forRowAtIndexPath: deleaget method of UITableView

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    }

Here please note that when you reload tableview or cell, the cell that is being removed will trigger this method. So implement additional logic inside this method to handle that situation.


问:
Kubernetes: how to change accessModes of auto scaled pod to ReadOnlyMany?
I'm trying HPA: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

PV:

```<code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: api-orientdb-pv
  labels:
    app: api-orientdb
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  gcePersistentDisk:
    pdName: api-orientdb-{{ .Values.cluster.name | default "testing" }}
    fsType: ext4
</code>```

PVC:

```<code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: api-orientdb-pv-claim
  labels:
    app: api
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      app: api-orientdb
  storageClassName: ""
</code>```

HPA:

```<code>Name:                           api-orientdb-deployment
Namespace:                      default
Labels:                         <none>
Annotations:                        <none>
CreationTimestamp:                  Thu, 08 Jun 2017 10:37:06 +0700
Reference:                      Deployment/api-orientdb-deployment
Metrics:                        ( current / target )
  resource cpu on pods  (as a percentage of request):   17% (8m) / 10%
Min replicas:                       1
Max replicas:                       2
Events:                         <none>
</code>```

and new pod has been created:

```<code>NAME                                       READY     STATUS    RESTARTS   AGE
api-orientdb-deployment-2506639415-n8nbt   1/1       Running   0          7h
api-orientdb-deployment-2506639415-x8nvm   1/1       Running   0          6h
</code>```

As you can see, I'm using gcePersistentDisk which does not support ReadWriteMany access mode.

Newly created pod also mount the volume as rw mode:

```<code>Name:        api-orientdb-deployment-2506639415-x8nvm
Containers:
    Mounts:
      /orientdb/databases from api-orientdb-persistent-storage (rw)
Volumes:
  api-orientdb-persistent-storage:
    Type:   PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  api-orientdb-pv-claim
    ReadOnly:   false
</code>```

Question: How does it work in this case? Is there a way to config the mainly pod (n8nbt) to use a PV with ReadWriteOnce access mode, and all other scaled pod (x8nvm) should be ReadOnlyMany? How to do it automatically?

The only way I can think of is create another PVC mount the same disk but with different accessModes, but then the question becomes to: how to config the newly scaled pod to use that PVC?

Fri Jun  9 11:29:34 ICT 2017

I found something: there is nothing ensure that the newly scaled pod will be run on the same node as the first pod. So, if the volume plugin does not support ReadWriteMany and the scaled pod is run on another node, it will failed to mount:

Failed to attach volume "api-orientdb-pv" on node
  "gke-testing-default-pool-7711f782-4p6f" with: googleapi: Error 400:
  The disk resource
  'projects/xx/zones/us-central1-a/disks/api-orientdb-testing' is
  already being used by
  'projects/xx/zones/us-central1-a/instances/gke-testing-default-pool-7711f782-h7xv'

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes

Important! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time.

If so, the only way to ensure that the HPA works is ReadWriteMany access mode must be supported by the volume plugin?

Fri Jun  9 14:28:30 ICT 2017

If you want only one Pod to be able to write then create two Deployments. One with replicas: 1 and the other one that has the autoscaler attached (and has readOnly: true in it)

OK.

Do note that a GCE PD can only be mounted by a single node if any of the Pods are accessing it readWrite.

Then I have to use label selectors to ensure that all pods end up on the same node, right?

Your question is not clear to me

Let me explain: in case of autoscaling, assuming that by using label selectors, I can ensure that newly scaled pod ends up on the same node, but since volume is mounted as rw, does it break the GCE PD as we have 2 pods mount a volume as rw?

First of all, generally, if you have a Deployment with replicas: 1 you won't have 2 Pod running at the same time (most of the time!!)

I know.

On the other hand if a PVC specifies ReadWriteOnce then after the first Pod is scheduled any other Pods will need to be scheduled on the same node or not be scheduled at all (most common case: there aren't enough resources on the Node)

In case of HPA, it does not. Please see my above updates for more details.

If for any reason you do have 2 Pods accessing the same mount readWrite then it's completely up the the application what will happen and is not kubernetes specific

The main thing made me confused is:

ReadWriteOnce – the volume can be mounted as read-write by a single node

OK, node, not pod. But in case of autoscaling, if 2 pods are running on the same node, and both mount the volume as rw, does GCE PD support it? If so, how does it work?

答:
It's working as intended. The Once in ReadWriteOnce refers to the number of Nodes that can use the PVC and not the number of Pods (HPA or no HPA).

If you want only one Pod to be able to write then create two Deployments. One with replicas: 1 and the other one that has the autoscaler attached (and has readOnly: true in it). Do note that a GCE PD can only be mounted by a single node if any of the Pods are accessing it readWrite.

Body:
I'm trying HPA: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: api-orientdb-pv
  labels:
    app: api-orientdb
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  gcePersistentDisk:
    pdName: api-orientdb-{{ .Values.cluster.name | default "testing" }}
    fsType: ext4

PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: api-orientdb-pv-claim
  labels:
    app: api
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      app: api-orientdb
  storageClassName: ""

HPA:

Name:                           api-orientdb-deployment
Namespace:                      default
Labels:                         <none>
Annotations:                        <none>
CreationTimestamp:                  Thu, 08 Jun 2017 10:37:06 +0700
Reference:                      Deployment/api-orientdb-deployment
Metrics:                        ( current / target )
  resource cpu on pods  (as a percentage of request):   17% (8m) / 10%
Min replicas:                       1
Max replicas:                       2
Events:                         <none>

and new pod has been created:

NAME                                       READY     STATUS    RESTARTS   AGE
api-orientdb-deployment-2506639415-n8nbt   1/1       Running   0          7h
api-orientdb-deployment-2506639415-x8nvm   1/1       Running   0          6h

As you can see, I'm using gcePersistentDisk which does not support ReadWriteMany access mode.

Newly created pod also mount the volume as rw mode:

Name:        api-orientdb-deployment-2506639415-x8nvm
Containers:
    Mounts:
      /orientdb/databases from api-orientdb-persistent-storage (rw)
Volumes:
  api-orientdb-persistent-storage:
    Type:   PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  api-orientdb-pv-claim
    ReadOnly:   false

Question: How does it work in this case? Is there a way to config the mainly pod (n8nbt) to use a PV with ReadWriteOnce access mode, and all other scaled pod (x8nvm) should be ReadOnlyMany? How to do it automatically?

The only way I can think of is create another PVC mount the same disk but with different accessModes, but then the question becomes to: how to config the newly scaled pod to use that PVC?

Fri Jun  9 11:29:34 ICT 2017

I found something: there is nothing ensure that the newly scaled pod will be run on the same node as the first pod. So, if the volume plugin does not support ReadWriteMany and the scaled pod is run on another node, it will failed to mount:

Failed to attach volume "api-orientdb-pv" on node
  "gke-testing-default-pool-7711f782-4p6f" with: googleapi: Error 400:
  The disk resource
  'projects/xx/zones/us-central1-a/disks/api-orientdb-testing' is
  already being used by
  'projects/xx/zones/us-central1-a/instances/gke-testing-default-pool-7711f782-h7xv'

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes

Important! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time.

If so, the only way to ensure that the HPA works is ReadWriteMany access mode must be supported by the volume plugin?

Fri Jun  9 14:28:30 ICT 2017

If you want only one Pod to be able to write then create two Deployments. One with replicas: 1 and the other one that has the autoscaler attached (and has readOnly: true in it)

OK.

Do note that a GCE PD can only be mounted by a single node if any of the Pods are accessing it readWrite.

Then I have to use label selectors to ensure that all pods end up on the same node, right?

Your question is not clear to me

Let me explain: in case of autoscaling, assuming that by using label selectors, I can ensure that newly scaled pod ends up on the same node, but since volume is mounted as rw, does it break the GCE PD as we have 2 pods mount a volume as rw?

First of all, generally, if you have a Deployment with replicas: 1 you won't have 2 Pod running at the same time (most of the time!!)

I know.

On the other hand if a PVC specifies ReadWriteOnce then after the first Pod is scheduled any other Pods will need to be scheduled on the same node or not be scheduled at all (most common case: there aren't enough resources on the Node)

In case of HPA, it does not. Please see my above updates for more details.

If for any reason you do have 2 Pods accessing the same mount readWrite then it's completely up the the application what will happen and is not kubernetes specific

The main thing made me confused is:

ReadWriteOnce – the volume can be mounted as read-write by a single node

OK, node, not pod. But in case of autoscaling, if 2 pods are running on the same node, and both mount the volume as rw, does GCE PD support it? If so, how does it work?