问:
C99 compatible nested calls within variadic macros
Need a way to support nested calls in variadic macros with optional argument. same as this but C99 compatible

GNU gcc extension for ## operator prevents nested calls from being expanded, see code below.

```<code>#define send(obj, msg, ...) find_method(obj, msg)(obj, ##__VA_ARGS__)

/* Ok */
send(0, "+", 1);
find_method(0, "+")(0, 1);

/* Ok. nested call as macros named argument */
send(send(5, "increment"), "+", 1);
find_method(find_method(5, "increment")(5), "+")(find_method(5, "increment")(5), 1);

/* Fail. nested call as macros variable argument i.e. `send` macro is not expanded */
send(0, "+", send(5, "increment"));
find_method(0, "+")(0, send(5, "increment"));

/*
 * preprocess with next commands
 *
 * gcc-4.9   -Wall -std=c99 -E -c file.c | less
 * clang-3.8 -Wall -std=c99 -E -c file.c | less
 */
</code>```

I've modified Jens Gustedt solution to place optional comma, see code below.

Are there more concise alternatives ?

```<code>#define _ARG16(              \
    _0,  _1,  _2,  _3,  _4,  \
    _5,  _6,  _7,  _8,  _9,  \
    _10, _11, _12, _13, _14, \
    _15, ...) _15
#define HAS_COMMA(...) \
    _ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
#define _TRIGGER_PARENTHESIS_(...) ,

#define OPTIONAL_COMMA(...)                                             \
    _ISEMPTY(                                                           \
          /* test if there is just one argument, eventually an empty    \
             one */                                                     \
          HAS_COMMA(__VA_ARGS__),                                       \
          /* test if _TRIGGER_PARENTHESIS_ together with the argument   \
             adds a comma */                                            \
          HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__),                 \
          /* test if the argument together with a parenthesis           \
             adds a comma */                                            \
          HAS_COMMA(__VA_ARGS__ (/*empty*/)),                           \
          /* test if placing it between _TRIGGER_PARENTHESIS_ and the   \
             parenthesis adds a comma */                                \
          HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (/*empty*/))      \
    )

#define SPACE_SYMBOL
#define COMMA_SYMBOL ,
#define ARG3(_0, _1, _2, ...) _2
#define OPTIONAL_COMMA_FROM(...) ARG3(__VA_ARGS__, SPACE_SYMBOL, COMMA_SYMBOL)

#define PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4
#define _ISEMPTY(_0, _1, _2, _3) \
    OPTIONAL_COMMA_FROM(PASTE5(_IS_EMPTY_CASE_, _0, _1, _2, _3))
#define _IS_EMPTY_CASE_0001 ,

#define send(obj, msg, ...) \
    find_method(obj, msg)(obj OPTIONAL_COMMA(__VA_ARGS__) __VA_ARGS__)

/* Ok */
send(0, "+", 1);

/* Ok */
send(send(5, "increment"), "+", 1);

/* Ok */
send(0, "+", send(5, "increment"));
</code>```

Update:

H Walters thanks for idea.

Didn't noticed approach with macros overloading in first place

```<code>#define SEND_NO_ARG(obj, msg) find_method(obj, msg)(obj)
#define SEND_ARG(obj, msg, ...) find_method(obj, msg)(obj, __VA_ARGS__)

#define GET_18TH_ARG(arg1, arg2, arg3, arg4, arg5,        \
    arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13,   \
    arg14, arg15, arg16, arg17, arg18, ...) arg18
#define SEND_MACRO_SELECTOR(...)                          \
    GET_18TH_ARG(__VA_ARGS__,                             \
        SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, \
        SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, \
        SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, \
        SEND_NO_ARG, )

#define send(...) SEND_MACRO_SELECTOR(__VA_ARGS__)(__VA_ARGS__)
</code>```

答:
This approach is slightly more concise (10 macros vs 12), and at least to my eyes a bit more organized (more of the macros are general purpose):

```<code>#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define FIRSTOFMANY(X,...) X
// This can be used as a pattern matcher on the first argument.
// Generally, the first argument is ignored; but if it's
// an object-like macro whose expansion has a comma, it can
// shift a new second argument in that's returned.
// Thus, you can build a "query pattern" as the first argument,
// pass a "default" as the second, and override the default with
// "matched pattern macros".
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
// Expands to a count of arguments (min 1, max 15).
#define COUNT(...) COUNT_I(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,)
#define COUNT_I(_,_15,_14,_13,_12,_11,_10,_9,_8,_7,_6,_5,_4,_3,_2,X,...) X

#define send(obj, ...) \
    find_method(obj, FIRSTOFMANY(__VA_ARGS__,)) \
    ( \
      /* select a macro based on ... count (default SEND_LONG) */ \
      SECOND(GLUE(WHEN_SEND_VCNT_EQ_,COUNT(__VA_ARGS__)),SEND_LONG)\
      (obj, __VA_ARGS__) \
    )
#define SEND_LONG(X,Y,...) X,__VA_ARGS__
// Use FIRSTOFMANY when send's varying arg count is 1
#define WHEN_SEND_VCNT_EQ_1 , FIRSTOFMANY
</code>```

...it's also C99 compliant (not relying on gnu extensions).

Body:
Need a way to support nested calls in variadic macros with optional argument. same as this but C99 compatible

GNU gcc extension for ## operator prevents nested calls from being expanded, see code below.

#define send(obj, msg, ...) find_method(obj, msg)(obj, ##__VA_ARGS__)

/* Ok */
send(0, "+", 1);
find_method(0, "+")(0, 1);

/* Ok. nested call as macros named argument */
send(send(5, "increment"), "+", 1);
find_method(find_method(5, "increment")(5), "+")(find_method(5, "increment")(5), 1);

/* Fail. nested call as macros variable argument i.e. `send` macro is not expanded */
send(0, "+", send(5, "increment"));
find_method(0, "+")(0, send(5, "increment"));

/*
 * preprocess with next commands
 *
 * gcc-4.9   -Wall -std=c99 -E -c file.c | less
 * clang-3.8 -Wall -std=c99 -E -c file.c | less
 */

I've modified Jens Gustedt solution to place optional comma, see code below.

Are there more concise alternatives ?

#define _ARG16(              \
    _0,  _1,  _2,  _3,  _4,  \
    _5,  _6,  _7,  _8,  _9,  \
    _10, _11, _12, _13, _14, \
    _15, ...) _15
#define HAS_COMMA(...) \
    _ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
#define _TRIGGER_PARENTHESIS_(...) ,

#define OPTIONAL_COMMA(...)                                             \
    _ISEMPTY(                                                           \
          /* test if there is just one argument, eventually an empty    \
             one */                                                     \
          HAS_COMMA(__VA_ARGS__),                                       \
          /* test if _TRIGGER_PARENTHESIS_ together with the argument   \
             adds a comma */                                            \
          HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__),                 \
          /* test if the argument together with a parenthesis           \
             adds a comma */                                            \
          HAS_COMMA(__VA_ARGS__ (/*empty*/)),                           \
          /* test if placing it between _TRIGGER_PARENTHESIS_ and the   \
             parenthesis adds a comma */                                \
          HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (/*empty*/))      \
    )

#define SPACE_SYMBOL
#define COMMA_SYMBOL ,
#define ARG3(_0, _1, _2, ...) _2
#define OPTIONAL_COMMA_FROM(...) ARG3(__VA_ARGS__, SPACE_SYMBOL, COMMA_SYMBOL)

#define PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4
#define _ISEMPTY(_0, _1, _2, _3) \
    OPTIONAL_COMMA_FROM(PASTE5(_IS_EMPTY_CASE_, _0, _1, _2, _3))
#define _IS_EMPTY_CASE_0001 ,

#define send(obj, msg, ...) \
    find_method(obj, msg)(obj OPTIONAL_COMMA(__VA_ARGS__) __VA_ARGS__)

/* Ok */
send(0, "+", 1);

/* Ok */
send(send(5, "increment"), "+", 1);

/* Ok */
send(0, "+", send(5, "increment"));

Update:

H Walters thanks for idea.

Didn't noticed approach with macros overloading in first place

#define SEND_NO_ARG(obj, msg) find_method(obj, msg)(obj)
#define SEND_ARG(obj, msg, ...) find_method(obj, msg)(obj, __VA_ARGS__)

#define GET_18TH_ARG(arg1, arg2, arg3, arg4, arg5,        \
    arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13,   \
    arg14, arg15, arg16, arg17, arg18, ...) arg18
#define SEND_MACRO_SELECTOR(...)                          \
    GET_18TH_ARG(__VA_ARGS__,                             \
        SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, \
        SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, \
        SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, SEND_ARG, \
        SEND_NO_ARG, )

#define send(...) SEND_MACRO_SELECTOR(__VA_ARGS__)(__VA_ARGS__)

Body:
This approach is slightly more concise (10 macros vs 12), and at least to my eyes a bit more organized (more of the macros are general purpose):

#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define FIRSTOFMANY(X,...) X
// This can be used as a pattern matcher on the first argument.
// Generally, the first argument is ignored; but if it's
// an object-like macro whose expansion has a comma, it can
// shift a new second argument in that's returned.
// Thus, you can build a "query pattern" as the first argument,
// pass a "default" as the second, and override the default with
// "matched pattern macros".
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
// Expands to a count of arguments (min 1, max 15).
#define COUNT(...) COUNT_I(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,)
#define COUNT_I(_,_15,_14,_13,_12,_11,_10,_9,_8,_7,_6,_5,_4,_3,_2,X,...) X

#define send(obj, ...) \
    find_method(obj, FIRSTOFMANY(__VA_ARGS__,)) \
    ( \
      /* select a macro based on ... count (default SEND_LONG) */ \
      SECOND(GLUE(WHEN_SEND_VCNT_EQ_,COUNT(__VA_ARGS__)),SEND_LONG)\
      (obj, __VA_ARGS__) \
    )
#define SEND_LONG(X,Y,...) X,__VA_ARGS__
// Use FIRSTOFMANY when send's varying arg count is 1
#define WHEN_SEND_VCNT_EQ_1 , FIRSTOFMANY

...it's also C99 compliant (not relying on gnu extensions).


来源: stackexchange

问:
ASP MVC3 with razor running on Azure
I would like to create a simple ASP MVC3 web applications for learning and have this hosted. I am familiar with ASP MVC but don't yet know much about the Azure cloud. If possible I would like to have these hosted on the cloud but I'm not sure where to start.

Can anyone give me any advice. For example for something very very low usage and making use of a SQL CE database what kind of azure account do I need and approximately how much would it cost.

Thanks in advance for your help.

答:
You can easily create an ASP.NET MVC project and host it on a single role. While @XIII is correct that you need to have two instances to get the Azure SLA, if you are just playing around a single instance will be fine. You should check out the special offers here: http://www.microsoft.com/windowsazure/offers/ With the Development Accelerator Core you get 750 hours of a small compute instance, which I believe you could swapped for 2x extra small insances for the same cost. (Double check this before you do it!) Additionally, you get 1 million storage transaction and 10gb of storage space. If you are starting with a new Azure app, I would recommend looking at blob storage and table storage rather than a traditional database. Azure Storage is much more scalable and will be much less expensive than SQL Azure for small scale deployments. I would suggest using the Windows Azure Toolkit to get started with table and blob storage.

I would stay away from trying to use SQL CE or any other database running on your Azure roles. That is going to be a lot more headache than it is worth for a simple deployment. If you must have a SQL database, you can get a 1gb SQL Azure instance for $10 per month.

ContentLicense: CC BY-SA 2.5

Title: ASP MVC3 with razor running on Azure


问:
Android: Uploading image without losing Exif data
In our app users have been uploading millions of images for years using (roughly) this code:

```<code>BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(postFilePath, bmOptions);
Bitmap roughBitmap = BitmapFactory.decodeFile(postFilePath, bmOptions);

ByteArrayOutputStream stream = new ByteArrayOutputStream();

roughBitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
InputStream fis = new ByteArrayInputStream(stream.toByteArray());

int fileSize = stream.toByteArray().length;
conn.setRequestProperty("Content-Length", Integer.toString(fileSize));
conn.setFixedLengthStreamingMode(fileSize);

...

if (fis != null) {
    byte[] buf = new byte[10240];

    int read;

    while ((read = fis.read(buf)) > 0) {
        os.write(buf, 0, read);
        totalBytesRead += read;
        if (uploadProgressListener != null) {
            try {
                uploadProgressListener.onBytesUploaded(read);
            } catch (Exception e) {
                Log.e(e);
            }
        }
    }

    fis.close();
}
</code>```

Recently we saw the need to preserve the Exif data of uploaded images. The problem is that the image Exif data is lost when compressing the bitmap. I thought of using ExifInterface for extracting this data from the original file:

```<code>ExifInterface oldExif = new ExifInterface(postFilePath);
String value = oldExif.getAttribute(ExifInterface.TAG_DATETIME);
</code>```

..and then adding it to the InputStream fis and then continue uploading the file. The problem is that ExifInterface cannot save Exif data to an InputStream.

How can Exif data be retained in the images when they'er uploaded to the server?

It's not a duplicate:
Just to clarify deeper, I've tried using the suggested duplicate question by using this method:

```<code>public static void copyExif(String originalPath, InputStream newStream) throws IOException {

    String[] attributes = new String[]
            {
                    ExifInterface.TAG_DATETIME,
                    ExifInterface.TAG_DATETIME_DIGITIZED,
                    ExifInterface.TAG_EXPOSURE_TIME,
                    ExifInterface.TAG_FLASH,
                    ExifInterface.TAG_FOCAL_LENGTH,
                    ExifInterface.TAG_GPS_ALTITUDE,
                    ExifInterface.TAG_GPS_ALTITUDE_REF,
                    ExifInterface.TAG_GPS_DATESTAMP,
                    ExifInterface.TAG_GPS_LATITUDE,
                    ExifInterface.TAG_GPS_LATITUDE_REF,
                    ExifInterface.TAG_GPS_LONGITUDE,
                    ExifInterface.TAG_GPS_LONGITUDE_REF,
                    ExifInterface.TAG_GPS_PROCESSING_METHOD,
                    ExifInterface.TAG_GPS_TIMESTAMP,
                    ExifInterface.TAG_MAKE,
                    ExifInterface.TAG_MODEL,
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.TAG_SUBSEC_TIME,
                    ExifInterface.TAG_WHITE_BALANCE
            };

    ExifInterface oldExif = new ExifInterface(originalPath);
    ExifInterface newExif = new ExifInterface(newStream);

    if (attributes.length > 0) {
        for (int i = 0; i < attributes.length; i++) {
            String value = oldExif.getAttribute(attributes[i]);
            if (value != null)
                newExif.setAttribute(attributes[i], value);
        }
        newExif.saveAttributes();
    }
}
</code>```

.. but got the exception java.io.IOException: ExifInterface does not support saving attributes for the current input. after newExif.saveAttributes(); because I'm trying to save the attributes to an InputStream. How else can I do it?

答:
The problem is that the image Exif data is lost when compressing the bitmap

The EXIF data is lost when reading in the Bitmap. A Bitmap has no EXIF tags.

How can Exif data be retained in the images when they'er uploaded to the server?

Stop reading in the Bitmap. Just upload the contents of postFilePath as-is. It will contain whatever EXIF tags it contains.

My assumption is that you are reading in the Bitmap in the hope that saving it again in 70% JPEG quality will result in meaningful bandwidth savings. I suspect that you are not saving very much, and you may be increasing the bandwidth in some cases (e.g., postFilePath points to a PNG). Your costs are a chunk of CPU time, an increased risk of an OutOfMemoryError, and the loss of your EXIF tags.

If, instead, the convert-to-70%-JPEG is some sort of data normalization approach, do that work on the server, where you have more CPU power, more disk space, more RAM, and continuous power.

ContentLicense: CC BY-SA 3.0

Body:
In our app users have been uploading millions of images for years using (roughly) this code:

BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(postFilePath, bmOptions);
Bitmap roughBitmap = BitmapFactory.decodeFile(postFilePath, bmOptions);

ByteArrayOutputStream stream = new ByteArrayOutputStream();

roughBitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
InputStream fis = new ByteArrayInputStream(stream.toByteArray());

int fileSize = stream.toByteArray().length;
conn.setRequestProperty("Content-Length", Integer.toString(fileSize));
conn.setFixedLengthStreamingMode(fileSize);

...

if (fis != null) {
    byte[] buf = new byte[10240];

    int read;

    while ((read = fis.read(buf)) > 0) {
        os.write(buf, 0, read);
        totalBytesRead += read;
        if (uploadProgressListener != null) {
            try {
                uploadProgressListener.onBytesUploaded(read);
            } catch (Exception e) {
                Log.e(e);
            }
        }
    }

    fis.close();
}

Recently we saw the need to preserve the Exif data of uploaded images. The problem is that the image Exif data is lost when compressing the bitmap. I thought of using ExifInterface for extracting this data from the original file:

ExifInterface oldExif = new ExifInterface(postFilePath);
String value = oldExif.getAttribute(ExifInterface.TAG_DATETIME);

..and then adding it to the InputStream fis and then continue uploading the file. The problem is that ExifInterface cannot save Exif data to an InputStream.

How can Exif data be retained in the images when they'er uploaded to the server?

It's not a duplicate:
Just to clarify deeper, I've tried using the suggested duplicate question by using this method:

public static void copyExif(String originalPath, InputStream newStream) throws IOException {

    String[] attributes = new String[]
            {
                    ExifInterface.TAG_DATETIME,
                    ExifInterface.TAG_DATETIME_DIGITIZED,
                    ExifInterface.TAG_EXPOSURE_TIME,
                    ExifInterface.TAG_FLASH,
                    ExifInterface.TAG_FOCAL_LENGTH,
                    ExifInterface.TAG_GPS_ALTITUDE,
                    ExifInterface.TAG_GPS_ALTITUDE_REF,
                    ExifInterface.TAG_GPS_DATESTAMP,
                    ExifInterface.TAG_GPS_LATITUDE,
                    ExifInterface.TAG_GPS_LATITUDE_REF,
                    ExifInterface.TAG_GPS_LONGITUDE,
                    ExifInterface.TAG_GPS_LONGITUDE_REF,
                    ExifInterface.TAG_GPS_PROCESSING_METHOD,
                    ExifInterface.TAG_GPS_TIMESTAMP,
                    ExifInterface.TAG_MAKE,
                    ExifInterface.TAG_MODEL,
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.TAG_SUBSEC_TIME,
                    ExifInterface.TAG_WHITE_BALANCE
            };

    ExifInterface oldExif = new ExifInterface(originalPath);
    ExifInterface newExif = new ExifInterface(newStream);

    if (attributes.length > 0) {
        for (int i = 0; i < attributes.length; i++) {
            String value = oldExif.getAttribute(attributes[i]);
            if (value != null)
                newExif.setAttribute(attributes[i], value);
        }
        newExif.saveAttributes();
    }
}

.. but got the exception java.io.IOException: ExifInterface does not support saving attributes for the current input. after newExif.saveAttributes(); because I'm trying to save the attributes to an InputStream. How else can I do it?


问:
Create CSV from form, store on server and move to remote server
I need to take data from a form and:

create a csv file (this part is done and working)

Upload to server (currently can only download)

Move to a remote server using ftp_put

Here is what I have so far, creating the .csv which currently just downloads.

```<code><?php
    if(isset($_POST['submit'])){

        //collect form data
        $email      = $_POST['inf_field_Email'];
        //other form data
        //server side validation
        if($email=='') {
            $error[] = 'Email is required';
        }
        //create csv
        if(!isset($error)){
        $Content = "Email\n";
        //set the data of the CSV
        $Content .= "$email\n";
        # set the file name and create CSV file
        $FileName = "FormData_".date("d-m-y-h:i:s").".csv";
        //this is where I can only create and download, I know the header is the issue here.
        header('Content-Type: application/csv');
        header('Content-Disposition: attachment; filename="' . $FileName . '"');
        echo $Content;
        exit();
        }
    }
?>
</code>```

I am just trying to store on server. I am on an AWS S3 running Apache.

Update

Per the advice below, I am now writing directly to a file on the server, however it is duplicating the header row with each submission.

```<code><?php
    //same form data and validation as above
    if(!isset($error)){
    $Content = "Email\n";
    $Content .= "$email\n";

    # set the file name and create CSV file
    $fp = fopen("Registration.csv","a");
    $savestring = $Content;
    fwrite($fp,$savestring);
    fclose($fp);
    echo"<h1>Your Data has been saved</h1>";
    exit();
}

</code>```

答:
In my opinion, you can combine first 2 steps without including host machine.

Create csv file on the server rather than your proposed 2-step process.

Move file to whenever you need but if you are moving to remote server: make sure you are encrypting your data and using https.

ContentLicense: CC BY-SA 4.0

Body:
I need to take data from a form and:

create a csv file (this part is done and working)

Upload to server (currently can only download)

Move to a remote server using ftp_put

Here is what I have so far, creating the .csv which currently just downloads.

<?php
    if(isset($_POST['submit'])){

        //collect form data
        $email      = $_POST['inf_field_Email'];
        //other form data
        //server side validation
        if($email=='') {
            $error[] = 'Email is required';
        }
        //create csv
        if(!isset($error)){
        $Content = "Email\n";
        //set the data of the CSV
        $Content .= "$email\n";
        # set the file name and create CSV file
        $FileName = "FormData_".date("d-m-y-h:i:s").".csv";
        //this is where I can only create and download, I know the header is the issue here.
        header('Content-Type: application/csv');
        header('Content-Disposition: attachment; filename="' . $FileName . '"');
        echo $Content;
        exit();
        }
    }
?>

I am just trying to store on server. I am on an AWS S3 running Apache.

Update

Per the advice below, I am now writing directly to a file on the server, however it is duplicating the header row with each submission.

<?php
    //same form data and validation as above
    if(!isset($error)){
    $Content = "Email\n";
    $Content .= "$email\n";

    # set the file name and create CSV file
    $fp = fopen("Registration.csv","a");
    $savestring = $Content;
    fwrite($fp,$savestring);
    fclose($fp);
    echo"
Your Data has been saved
";
    exit();
}


答:
Put Latitude on the Rows shelf, and then right click on the pill and convert it to a dimension. Make sure it stays continuous.

Likewise, put Longitude on the Columns shelf and convert it to a dimension

Put SUM(Number of Records) on the size shelf

Important, Don't have any other dimensions on any shelves, leave SeqId off

This approach will make one mark for each unique latitude/longitude pair and size that mark according to how many times that pair appears in the data set.

A problem you will probably notice is that two latitudes that differ only in the final decimal place are treated as distinct latitudes. That may not make the most useful visualization. You can bin nearby latitudes together by making a calculated field to round values to the degree you wish. If you do that, be sure to make your field a continuous dimension, and also set its geographic role. It has the effect of snapping lat/long pairs to a grid. As an alternative to rounding, you can look into the hexbinx() and hexbiny() functions.

For a heat map based on square or hex grids, you may want to try using (partially transparent) colors instead of size to indicate density.

Title: Tableau: How to display size as the number of records for the same lat,long

Body:
On the same (lat,long) on a Tableau-Desktop map, I want the size of a dot  to be proportional to the number of records at that location. I tried count/sum(Number of Records) built-in tableau measure, I created a SeqId and tried count(SeqId) for Size, neither worked. Here is a sample of my data, as you can see:
(44.92810490,-74.89186500) has one Record
(44.69948730,-73.45291240) has five Records
(44.72143010,-73.72375280) has 10 records
I would like the point to be proportional to the number of records at that location.   Help is Much appreciated
Musa
Seq Id,Census,Gender,Lat,Long
1,1860,F,44.92810490,-74.89186500
2,1870,M,44.69948730,-73.45291240
3,1870,F,44.69948730,-73.45291240
4,1870,M,44.69948730,-73.45291240
5,1870,F,44.69948730,-73.45291240
6,1870,F,44.69948730,-73.45291240
7,1870,M,44.72143010,-73.72375280
8,1870,M,44.72143010,-73.72375280
9,1870,M,44.72143010,-73.72375280
10,1870,M,44.72143010,-73.72375280
11,1870,M,44.72143010,-73.72375280
12,1870,M,44.72143010,-73.72375280
13,1870,M,44.72143010,-73.72375280
14,1870,M,44.72143010,-73.72375280
15,1870,M,44.72143010,-73.72375280
16,1870,M,44.72143010,-73.72375280


问:
Binding element property from another xaml
Well, I have a style file that defines a custom dock panel for my MainWindow.

```<code>Title="Fancy App" Width="900" Height="730" Background="#37537F" WindowStyle="None" AllowsTransparency="True" >

<Window.Style>
    <StaticResource ResourceKey="CustomWindowStyle"/>
</Window.Style>
</code>```

The CustomWindowStyle.xaml defines some viewboxes for the controllers like minimize, maximize, etc. Something like that:

```<code><Viewbox DockPanel.Dock="Right" Visibility="Visible">
<Border Width="74" Background="Transparent" MouseLeftButtonDown="MaximizeRestoreClick" WindowChrome.IsHitTestVisibleInChrome="True">
    <Canvas Width="48" Height="48" >
        <Path Margin="10" Data="M4,4H20V20H4V4M6,8V18H18V8H6Z" Fill="White"/>
    </Canvas>
</Border>
</code>```

So far so good.
What I want to achieve now is to access, let's say, the Visibility property of the Viewbox in the CustomWindowStyle from the MainWindow.xaml and change it.
I have no idea how to do that.

答:
You could give the Viewbox in your template an x:Name:

```<code><Viewbox x:Name="viewBox">
...
</code>```

...and override the OnApplyTemplate() method of your window class:

```<code>public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        Viewbox vb = this.Template.FindName("viewBox", this) as Viewbox;
        if (vb != null)
            vb.Visibility = Visibility.Collapsed;
    }
}
</code>```

You won't be able to access the Viewbox that you have defined in your Style/ControlTemplate from the XAML markup of the window.

Body:
Well, I have a style file that defines a custom dock panel for my MainWindow.

Title="Fancy App" Width="900" Height="730" Background="#37537F" WindowStyle="None" AllowsTransparency="True" >

<Window.Style>
    <StaticResource ResourceKey="CustomWindowStyle"/>
</Window.Style>

The CustomWindowStyle.xaml defines some viewboxes for the controllers like minimize, maximize, etc. Something like that:

<Viewbox DockPanel.Dock="Right" Visibility="Visible">
<Border Width="74" Background="Transparent" MouseLeftButtonDown="MaximizeRestoreClick" WindowChrome.IsHitTestVisibleInChrome="True">
    <Canvas Width="48" Height="48" >
        <Path Margin="10" Data="M4,4H20V20H4V4M6,8V18H18V8H6Z" Fill="White"/>
    </Canvas>
</Border>

So far so good.
What I want to achieve now is to access, let's say, the Visibility property of the Viewbox in the CustomWindowStyle from the MainWindow.xaml and change it.
I have no idea how to do that.

Body:
You could give the Viewbox in your template an x:Name:

<Viewbox x:Name="viewBox">
...

...and override the OnApplyTemplate() method of your window class:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        Viewbox vb = this.Template.FindName("viewBox", this) as Viewbox;
        if (vb != null)
            vb.Visibility = Visibility.Collapsed;
    }
}

You won't be able to access the Viewbox that you have defined in your Style/ControlTemplate from the XAML markup of the window.


问:
How to make the following code type safe?
say, I have a generic command trait with an execute method that takes an Input and returns an Output. Something like

```<code>trait Input;
trait Output;

trait Command[I <: Input, O <: Output] {
  def execute(input: I): O;
}
</code>```

Then, I am going to create various Commands, something like

```<code>class SampleInput extends Input
class SampleOutput extends Output

class SampleCommand extends Command[SampleInput, SampleOutput] {
  def execute(input:SampleInput):SampleOutput = new SampleOutput()
}
</code>```

The problem with this is I could create a Command with a SampleAInput and SampleBOutput and the compiler will accept that happily. How do I enforce that so the compiler fails with type mismatch error ?

Somehow, I need to group Input and Output under a type and pass that type to create a
command. How do I do that?

答:
I'm a little bit late, but how about this:</p>

```<code>object inout {

  trait ~>[I, O]

  trait FooInput
  trait FooOutput

  trait BarOutput

  //this specifies a valid input-output combination
  implicit object fooInOut extends ~>[FooInput,FooOutput]

  class Command[I, O](implicit val valid: I ~> O) {
    def execute(input: I): O;
  }

  class FooCommand extends Command[FooInput, FooOutput]

  //won't compile:
  //class FubarCommand extends Command[FooInput, BarOutput]
}
</code>```

Body:
say, I have a generic command trait with an execute method that takes an Input and returns an Output. Something like

trait Input;
trait Output;

trait Command[I <: Input, O <: Output] {
  def execute(input: I): O;
}

Then, I am going to create various Commands, something like

class SampleInput extends Input
class SampleOutput extends Output

class SampleCommand extends Command[SampleInput, SampleOutput] {
  def execute(input:SampleInput):SampleOutput = new SampleOutput()
}

The problem with this is I could create a Command with a SampleAInput and SampleBOutput and the compiler will accept that happily. How do I enforce that so the compiler fails with type mismatch error ?

Somehow, I need to group Input and Output under a type and pass that type to create a
command. How do I do that?

Body:
I'm a little bit late, but how about this:

object inout {

  trait ~>[I, O]

  trait FooInput
  trait FooOutput

  trait BarOutput

  //this specifies a valid input-output combination
  implicit object fooInOut extends ~>[FooInput,FooOutput]

  class Command[I, O](implicit val valid: I ~> O) {
    def execute(input: I): O;
  }

  class FooCommand extends Command[FooInput, FooOutput]

  //won't compile:
  //class FubarCommand extends Command[FooInput, BarOutput]
}


问:
OrientDB: What are Class Properties used for ?
I'm new to OrientDB and I understood that classes can have properties and in this case they actually act as tables in relational databases. However, I found out that even if I define properties for a class, it still doesn't guarantee that a document created from this class has a value for all its properties.

For example:
Here, I define a class 'Person' with a property 'name', and I still insert a new document to this class although it doesn't have a value for this property.
If so, what is the purpose of properties and how can I make sure that documents that do NOT include a value for a certain property will not be inserted into the class?

orientdb {db=GratefulDeadConcerts}> create class person

Class created successfully. Total classes in database now: 17.

orientdb {db=GratefulDeadConcerts}> create property person.name string

Property created successfully with id=1.

orientdb {db=GratefulDeadConcerts}> insert into person content
  {"phone":"1234"}

Inserted record 'person#66:0{phone:1234} v1' in 0.000000 sec(s).

orientdb {db=GratefulDeadConcerts}> select from person

+----+-----+------+-----+
  |#   |@RID |@CLASS|phone|
  +----+-----+------+-----+
  |0   |#66:0|person|1234 |
  +----+-----+------+-----+

答:
In OrientDB you can work in schema-less, schema-hybrid or schema-full.
You can define properties and you can define constraints on each property:

http://orientdb.com/docs/last/SQL-Create-Property.html

At the same time you can define indexes on property:

http://orientdb.com/docs/last/Indexes.html

For example, if you want that a property has unique values over the entire class (a primary key), just define a unique index:

CREATE INDEX Person.name ON Person (name) UNIQUE

hope this help


问:
Regex exercise in R
I want to parse a string using R, and I'd like to get out a list of objects. Brackets, spaces and commas in the string dictate the structure of the final list:

each pair of brackets is separated by a space and the words in each pair of brackets has to form a new object of the list;

words in brackets are separated by comma and should form different elements in each listed object;

the mentioned structure can also be found nested within a pair of brackets.

Here is an example of the string:

```<code>x <- "(K01596,K01610) (K01689) (K01834,K15633,K15634,K15635) (K00927) (K00134,K00150) (K01803) ((K01623,K01624,K11645) (K03841,K02446,K11532,K01086,K04041),K01622)"
</code>```

The desired output should like this:

```<code>list(c("K01596","K01610"), "K01689", c("K01834","K15633","K15634","K15635"), "K00927", c("K00134","K00150"), "K01803", list(list(c("K01623","K01624","K11645"), c("K03841","K02446","K11532","K01086","K04041")), "K01622"))
</code>```

I manage to solve how to do the parsing for case 1)

```<code>match <- gregexpr("\\((?>[^()]|(?R))*\\)", x, perl = T)
x2 <- as.list(substring(x, match[[1]], match[[1]] + attr(match[[1]], "match.length") - 1))
</code>```

and case 2) is also easy, I can just remove the brackets with gsub and split the words using strsplit.
The problem is how to parse case 3), when I have a nested level like:

```<code>((K01623,K01624,K11645) (K03841,K02446,K11532,K01086,K04041),K01622)
</code>```

and I have to get out a listed object that is a list itself:

```<code>list(list(c("K01623","K01624","K11645"), c("K03841","K02446","K11532","K01086","K04041")), "K01622")
</code>```

答:
I suggest you apply the regex you already found for case 1) recursively to the input. That is, call your recursive function for each match found.

If no match is found you are in case 2) and can just use strsplit on the input. I have put together an example function below:

```<code>constructList <- function(x) {

  matches <- gregexpr("\\((?>[^()]|(?R))*\\)", x, perl = T)

  if (matches[[1]][1] == -1) {
    return(strsplit(x, ",")[[1]])
  }

  lapply(
    lapply(1:length(matches[[1]]), function(i)
                                        substr(x,
                                               matches[[1]][i] + 1,
                                               matches[[1]][i] + attr(matches[[1]], "match.length")[i] - 2)),
    constructList)

}
</code>```

Output seems OK:

```<code>constructList(x)
[[1]]
[1] "K01596" "K01610"

[[2]]
[1] "K01689"

[[3]]
[1] "K01834" "K15633" "K15634" "K15635"

[[4]]
[1] "K00927"

[[5]]
[1] "K00134" "K00150"

[[6]]
[1] "K01803"

[[7]]
[[7]][[1]]
[1] "K01623" "K01624" "K11645"

[[7]][[2]]
[1] "K03841" "K02446" "K11532" "K01086" "K04041"
</code>```

Title: Regex exercise in R

Body:
I want to parse a string using R, and I'd like to get out a list of objects. Brackets, spaces and commas in the string dictate the structure of the final list:

each pair of brackets is separated by a space and the words in each pair of brackets has to form a new object of the list;

words in brackets are separated by comma and should form different elements in each listed object;

the mentioned structure can also be found nested within a pair of brackets.

Here is an example of the string:

x <- "(K01596,K01610) (K01689) (K01834,K15633,K15634,K15635) (K00927) (K00134,K00150) (K01803) ((K01623,K01624,K11645) (K03841,K02446,K11532,K01086,K04041),K01622)"

The desired output should like this:

list(c("K01596","K01610"), "K01689", c("K01834","K15633","K15634","K15635"), "K00927", c("K00134","K00150"), "K01803", list(list(c("K01623","K01624","K11645"), c("K03841","K02446","K11532","K01086","K04041")), "K01622"))

I manage to solve how to do the parsing for case 1)

match <- gregexpr("\\((?>[^()]|(?R))*\\)", x, perl = T)
x2 <- as.list(substring(x, match[[1]], match[[1]] + attr(match[[1]], "match.length") - 1))

and case 2) is also easy, I can just remove the brackets with gsub and split the words using strsplit.
The problem is how to parse case 3), when I have a nested level like:

((K01623,K01624,K11645) (K03841,K02446,K11532,K01086,K04041),K01622)

and I have to get out a listed object that is a list itself:

list(list(c("K01623","K01624","K11645"), c("K03841","K02446","K11532","K01086","K04041")), "K01622")

Body:
I suggest you apply the regex you already found for case 1) recursively to the input. That is, call your recursive function for each match found.

If no match is found you are in case 2) and can just use strsplit on the input. I have put together an example function below:

constructList <- function(x) {

  matches <- gregexpr("\\((?>[^()]|(?R))*\\)", x, perl = T)

  if (matches[[1]][1] == -1) {
    return(strsplit(x, ",")[[1]])
  }

  lapply(
    lapply(1:length(matches[[1]]), function(i)
                                        substr(x,
                                               matches[[1]][i] + 1,
                                               matches[[1]][i] + attr(matches[[1]], "match.length")[i] - 2)),
    constructList)

}

Output seems OK:

constructList(x)
[[1]]
[1] "K01596" "K01610"

[[2]]
[1] "K01689"

[[3]]
[1] "K01834" "K15633" "K15634" "K15635"

[[4]]
[1] "K00927"

[[5]]
[1] "K00134" "K00150"

[[6]]
[1] "K01803"

[[7]]
[[7]][[1]]
[1] "K01623" "K01624" "K11645"

[[7]][[2]]
[1] "K03841" "K02446" "K11532" "K01086" "K04041"


问:
How to set SmartFilter entitySet
When I try to filter something(smartFilter), I'm getting a 404 error, checking my payload I see that there is no entity in it:

```<code>GET null/$count?$filter=startswith(undefined,22) HTTP/1.1
</code>```

this one is working

```<code>GET RfcSearchRequisitionsSet?$skip=0&$top=100&$filter=(Banfn%20eq%20%2722%27)&$select=Bsart%2cBanfn%2cBnfpo%2cWerks HTTP/1.1
</code>```

XML

```<code>                <smartFilterBar:SmartFilterBar id="smartFilterBar"
                    entityType="RfcSearchRequisitions">
                    <smartFilterBar:controlConfiguration>
                        <smartFilterBar:ControlConfiguration
                            key="Banfn" index="1" groupId="_BASIC" width="300px"
                            visibleInAdvancedArea="true">

                        </smartFilterBar:ControlConfiguration>
                    </smartFilterBar:controlConfiguration>
                </smartFilterBar:SmartFilterBar>
                <smartTable:SmartTable id="smartTable"
                    entitySet="RfcSearchRequisitionsSet" smartFilterId="smartFilterBar"...>
</code>```

Annotations

```<code><Annotation Term="com.sap.vocabularies.UI.v1.LineItem">
<Collection>
<Record Type="com.sap.vocabularies.UI.v1.DataFieldForAnnotation">
<PropertyValue Property="Label" String="DocType"/>
<PropertyValue Property="Target" AnnotationPath="BSART"/>
</Record>
</code>```

答:
The problems are with the annotations, they should be like:</p>

```<code><Record Type="com.sap.vocabularies.UI.v1.DataField">
    <PropertyValue Property="Label" String="DateCreated"/>
     <PropertyValue Property="Value" Path="Erdat"/>
</Record>
</code>```

Title: How to set SmartFilter entitySet

Body:
When I try to filter something(smartFilter), I'm getting a 404 error, checking my payload I see that there is no entity in it:

GET null/$count?$filter=startswith(undefined,22) HTTP/1.1

this one is working

GET RfcSearchRequisitionsSet?$skip=0&$top=100&$filter=(Banfn%20eq%20%2722%27)&$select=Bsart%2cBanfn%2cBnfpo%2cWerks HTTP/1.1

XML

                <smartFilterBar:SmartFilterBar id="smartFilterBar"
                    entityType="RfcSearchRequisitions">
                    <smartFilterBar:controlConfiguration>
                        <smartFilterBar:ControlConfiguration
                            key="Banfn" index="1" groupId="_BASIC" width="300px"
                            visibleInAdvancedArea="true">

                        </smartFilterBar:ControlConfiguration>
                    </smartFilterBar:controlConfiguration>
                </smartFilterBar:SmartFilterBar>
                <smartTable:SmartTable id="smartTable"
                    entitySet="RfcSearchRequisitionsSet" smartFilterId="smartFilterBar"...>

Annotations

<Annotation Term="com.sap.vocabularies.UI.v1.LineItem">
<Collection>
<Record Type="com.sap.vocabularies.UI.v1.DataFieldForAnnotation">
<PropertyValue Property="Label" String="DocType"/>
<PropertyValue Property="Target" AnnotationPath="BSART"/>
</Record>

Body:
The problems are with the annotations, they should be like:

<Record Type="com.sap.vocabularies.UI.v1.DataField">
    <PropertyValue Property="Label" String="DateCreated"/>
     <PropertyValue Property="Value" Path="Erdat"/>
</Record>


问:
RXJS expand operator
```<code>var offset = 1;
var limit = 500;

var list = new Promise(function (resolve, reject) {
  rets.getAutoLogoutClient(config.clientSettings, (client) => {
    var results = client.search.query(SearchType, Class, Query, {
      limit: limit,
      offset: offset
    });
    resolve(results);
  });
});

var source = Rx.Observable.fromPromise(list);

source.subscribe(results => console.log(results.count));
</code>```

I am doing a real estate site, using RETS.

What I am trying to do my query are limited from the RETS server, is run this in a loop increasing my Offset until I have all my data. I don't know what the count is until I run the query and find the count value.

I have tried to use expand but I have no clue of how exactly it works. Tried to do these multiple ways, even using the old fashion while loop, which while doesn't work with .then method. So I have turned to RXJS since I been using it in Angular 4.

This is done in express. I need to eventually run corn jobs to fetch for updated properties, but my problem is fetching all the data and increasing the offset each time if the count is higher than my offset. So for example, run a query with an offset of 1 with a limit of 500. Total here is 1690. So next go around my offset would be:

```<code>offset += limit
</code>```

Once I have my data, I need to save it to MongoDB. Which I already been able successfully to do. It's just finding a way to get all the data without having to manually set my offset.

Note the server limit is 2500, yes I can fetch all this in one shot but there are also other data, such as media, which could have well over 2500.

Any suggestions?

答:
```<code>const retsConnect = Rx.Observable.create(function(observer) {
  rets.getAutoLogoutClient(config.clientSettings, client => {
    return searchQuery(client, 500, 1, observer);
  });
});

function searchQuery(client, limit, offset, observer) {
  let currentOffset = offset === undefined || offset === 0 ? 1 : offset;
  return client.search.query(SearchType, Class, Query, {limit: limit, offset: currentOffset})
    .then(results => {
      offset += limit;
      observer.next(results.maxRowsExceeded);
      if (results.maxRowsExceeded) {
        console.log(offset);
        return searchQuery(client, limit, offset, observer);
      } else {
        console.log('Completed');
        observer.complete();
      }
    });
}

retsConnect.subscribe(val => console.log(val));
</code>```

So this is getting somewhere with what I have tried here. I am still in process of tweaking this. So what I am looking to do is break the searchQuery down more. Not sure if I should be passing observer.next there, so I am going to is figure out where to map and takeUntil install of returning searchQuery again. I'm not sure takeUntil will take a true or false though. All I need this data to do is be saved into mongodb. So I guess I could leave it like this and have my save method put in there, but I still like to figure this out.

Note: results.maxRowsExceeded returns true when there are still more data. So once the maxRows returns false, it will stop and all the data has been fetched.

Title: RXJS expand operator

Body:
var offset = 1;
var limit = 500;

var list = new Promise(function (resolve, reject) {
  rets.getAutoLogoutClient(config.clientSettings, (client) => {
    var results = client.search.query(SearchType, Class, Query, {
      limit: limit,
      offset: offset
    });
    resolve(results);
  });
});

var source = Rx.Observable.fromPromise(list);

source.subscribe(results => console.log(results.count));

I am doing a real estate site, using RETS.

What I am trying to do my query are limited from the RETS server, is run this in a loop increasing my Offset until I have all my data. I don't know what the count is until I run the query and find the count value.

I have tried to use expand but I have no clue of how exactly it works. Tried to do these multiple ways, even using the old fashion while loop, which while doesn't work with .then method. So I have turned to RXJS since I been using it in Angular 4.

This is done in express. I need to eventually run corn jobs to fetch for updated properties, but my problem is fetching all the data and increasing the offset each time if the count is higher than my offset. So for example, run a query with an offset of 1 with a limit of 500. Total here is 1690. So next go around my offset would be:

offset += limit

Once I have my data, I need to save it to MongoDB. Which I already been able successfully to do. It's just finding a way to get all the data without having to manually set my offset.

Note the server limit is 2500, yes I can fetch all this in one shot but there are also other data, such as media, which could have well over 2500.

Any suggestions?

Body:
const retsConnect = Rx.Observable.create(function(observer) {
  rets.getAutoLogoutClient(config.clientSettings, client => {
    return searchQuery(client, 500, 1, observer);
  });
});

function searchQuery(client, limit, offset, observer) {
  let currentOffset = offset === undefined || offset === 0 ? 1 : offset;
  return client.search.query(SearchType, Class, Query, {limit: limit, offset: currentOffset})
    .then(results => {
      offset += limit;
      observer.next(results.maxRowsExceeded);
      if (results.maxRowsExceeded) {
        console.log(offset);
        return searchQuery(client, limit, offset, observer);
      } else {
        console.log('Completed');
        observer.complete();
      }
    });
}

retsConnect.subscribe(val => console.log(val));

So this is getting somewhere with what I have tried here. I am still in process of tweaking this. So what I am looking to do is break the searchQuery down more. Not sure if I should be passing observer.next there, so I am going to is figure out where to map and takeUntil install of returning searchQuery again. I'm not sure takeUntil will take a true or false though. All I need this data to do is be saved into mongodb. So I guess I could leave it like this and have my save method put in there, but I still like to figure this out.

Note: results.maxRowsExceeded returns true when there are still more data. So once the maxRows returns false, it will stop and all the data has been fetched.


问:
How to connect link to an edit form
I need a form that allows a user to edit data from an SQL database.

The main page of my form contains a table where any available data is shown and, also, there are edit and delete options available. Sample:

```<code>{
$row=mysql_fetch_array($result);
echo "<tr>";
echo "<td>".$row["name"]."</td>";
echo "<td>".$row["occuptation"]."</td>";
echo '<td><a href="edit.php"><img src="edit.png"/></a></td>';
echo '<td><a href="delete.php"><img src="delete.png"/></a></td>';
echo "</tr>";
}
</code>```

When the user clicks the edit.png I need it to direct to edit.php where the data from the whole row selected (whichever row the user chooses to click edit or delete from) shows up in a form (like default values). I have no idea how to achieve this.

Any help is appreciated! Please tell me if i'm being confusing and I will try to explain further.

答:
```<code> $selectQuery = mysqli_query($database, "SELECT * FROM products");
   if($selectQuery){
              while ($row =mysqli_fetch_array($selectQuery)){
              <td><a href="delete.php?editid=<?php echo $row['id'];?>">
              <img src="delete.png"/></a></td><?php } }?>

echo '<td><a href="delete.php?id=' . $row["id"] . '"><img src="delete.png"/></a></td>';
</code>```

Title: How to connect link to an edit form

Body:
I need a form that allows a user to edit data from an SQL database.

The main page of my form contains a table where any available data is shown and, also, there are edit and delete options available. Sample:

{
$row=mysql_fetch_array($result);
echo "
";
echo "".$row["name"]."	";
echo "".$row["occuptation"]."	";
echo '	';
echo '	';
echo "
";
}

When the user clicks the edit.png I need it to direct to edit.php where the data from the whole row selected (whichever row the user chooses to click edit or delete from) shows up in a form (like default values). I have no idea how to achieve this.

Any help is appreciated! Please tell me if i'm being confusing and I will try to explain further.