问:
How to get the Full file path from URI
I'd like to get the full file path, from a URI. The URI isn't a Image, but it's a music file, but if i do it like the MediaStore Solution, it won't work if the app user selects eg Astro as browser, instead of Music Player. How do I solve this?</p>

答:
To get any sort of file path use this (taken from https://github.com/iPaulPro/aFileChooser)         </p>

```<code>package com.yourpackage;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;
import java.io.FileFilter;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.List;

/**
 * @author Peli
 * @author paulburke (ipaulpro)
 * @version 2013-12-11
 */
public class FileUtils {
    private FileUtils() {
    } //private constructor to enforce Singleton pattern

    /**
     * TAG for log messages.
     */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = true; // Set to true to enable logging

    public static final String MIME_TYPE_AUDIO = "audio/*";
    public static final String MIME_TYPE_TEXT = "text/*";
    public static final String MIME_TYPE_IMAGE = "image/*";
    public static final String MIME_TYPE_VIDEO = "video/*";
    public static final String MIME_TYPE_APP = "application/*";

    public static final String HIDDEN_PREFIX = ".";

    /**
     * Gets the extension of a file name, like ".png" or ".jpg".
     *
     * @param uri
     * @return Extension including the dot("."); "" if there is no extension;
     * null if uri was null.
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }

    /**
     * @return True if Uri is a MediaStore Uri.
     * @author paulburke
     */
    public static boolean isMediaUri(Uri uri) {
        return "media".equalsIgnoreCase(uri.getAuthority());
    }

    /**
     * Convert File into Uri.
     *
     * @param file
     * @return uri
     */
    public static Uri getUri(File file) {
        if (file != null) {
            return Uri.fromFile(file);
        }
        return null;
    }

    /**
     * Returns the path only (without file name).
     *
     * @param file
     * @return
     */
    public static File getPathWithoutFilename(File file) {
        if (file != null) {
            if (file.isDirectory()) {
                // no file to be split off. Return everything
                return file;
            } else {
                String filename = file.getName();
                String filepath = file.getAbsolutePath();

                // Construct path without file name.
                String pathwithoutname = filepath.substring(0,
                        filepath.length() - filename.length());
                if (pathwithoutname.endsWith("/")) {
                    pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
                }
                return new File(pathwithoutname);
            }
        }
        return null;
    }

    /**
     * @return The MIME type for the given file.
     */
    public static String getMimeType(File file) {

        String extension = getExtension(file.getName());

        if (extension.length() > 0)
            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));

        return "application/octet-stream";
    }

    /**
     * @return The MIME type for the give Uri.
     */
    public static String getMimeType(Context context, Uri uri) {
        File file = new File(getPath(context, uri));
        return getMimeType(file);
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is {@link LocalStorageProvider}.
     * @author paulburke
     */
    public static boolean isLocalStorageDocument(Uri uri) {
        return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     * @author paulburke
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     * @author paulburke
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);

                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * Get a file path from a Uri. This will quickGet the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     * @see #isLocal(String)
     * @see #getFile(Context, Uri)
     */
    public static String getPath(final Context context, final Uri uri) {

        if (DEBUG)
            Log.d(TAG + " File -",
                    "Authority: " + uri.getAuthority() +
                            ", Fragment: " + uri.getFragment() +
                            ", Port: " + uri.getPort() +
                            ", Query: " + uri.getQuery() +
                            ", Scheme: " + uri.getScheme() +
                            ", Host: " + uri.getHost() +
                            ", Segments: " + uri.getPathSegments().toString()
            );
        // DocumentProvider
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

//                if ("primary".equalsIgnoreCase(type)) {
//                    return Environment.getExternalStorageDirectory() + "/" + split[1];
//                }
                return Environment.getExternalStorageDirectory() + "/" + split[1];

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                try {
                    final String id = DocumentsContract.getDocumentId(uri);
                    Log.d(TAG, "getPath: id= " + id);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }catch (Exception e){
                    e.printStackTrace();
                    List<String> segments = uri.getPathSegments();
                    if(segments.size() > 1) {
                        String rawPath = segments.get(1);
                        if(!rawPath.startsWith("/")){
                            return rawPath.substring(rawPath.indexOf("/"));
                        }else {
                            return rawPath;
                        }
                    }
                }
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Convert Uri into File, if possible.
     *
     * @return file A local file that the Uri was pointing to, or null if the
     * Uri is unsupported or pointed to a remote resource.
     * @author paulburke
     * @see #getPath(Context, Uri)
     */
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }

    /**
     * Get the file size in a human-readable string.
     *
     * @param size
     * @return
     * @author paulburke
     */
    public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

    /**
     * Attempt to retrieve the thumbnail of given File from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param file
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, File file) {
        return getThumbnail(context, getUri(file), getMimeType(file));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri) {
        return getThumbnail(context, uri, getMimeType(context, uri));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @param mimeType
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
        if (DEBUG)
            Log.d(TAG, "Attempting to quickGet thumbnail");

        if (!isMediaUri(uri)) {
            Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
            return null;
        }

        Bitmap bm = null;
        if (uri != null) {
            final ContentResolver resolver = context.getContentResolver();
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, null, null, null, null);
                if (cursor.moveToFirst()) {
                    final int id = cursor.getInt(0);
                    if (DEBUG)
                        Log.d(TAG, "Got thumb ID: " + id);

                    if (mimeType.contains("video")) {
                        bm = MediaStore.Video.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Video.Thumbnails.MINI_KIND,
                                null);
                    } else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
                        bm = MediaStore.Images.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Images.Thumbnails.MINI_KIND,
                                null);
                    }
                }
            } catch (Exception e) {
                if (DEBUG)
                    Log.e(TAG, "getThumbnail", e);
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }
        return bm;
    }

    /**
     * File and folder comparator. TODO Expose sorting option method
     *
     * @author paulburke
     */
    public static Comparator<File> sComparator = new Comparator<File>() {
        @Override
        public int compare(File f1, File f2) {
            // Sort alphabetically by lower case, which is much cleaner
            return f1.getName().toLowerCase().compareTo(
                    f2.getName().toLowerCase());
        }
    };

    /**
     * File (not directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sFileFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return files only (not directories) and skip hidden files
            return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Folder (directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sDirFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return directories only and skip hidden directories
            return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Get the Intent for selecting content to be used in an Intent Chooser.
     *
     * @return The intent for opening a file with Intent.createChooser()
     * @author paulburke
     */
    public static Intent createGetContentIntent() {
        // Implicitly allow the user to select a particular kind of data
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // The MIME data type filter
        intent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        return intent;
    }
}
</code>```

Title: How to get the Full file path from URI

Body:
To get any sort of file path use this (taken from https://github.com/iPaulPro/aFileChooser)

package com.yourpackage;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;
import java.io.FileFilter;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.List;

/**
 * @author Peli
 * @author paulburke (ipaulpro)
 * @version 2013-12-11
 */
public class FileUtils {
    private FileUtils() {
    } //private constructor to enforce Singleton pattern

    /**
     * TAG for log messages.
     */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = true; // Set to true to enable logging

    public static final String MIME_TYPE_AUDIO = "audio/*";
    public static final String MIME_TYPE_TEXT = "text/*";
    public static final String MIME_TYPE_IMAGE = "image/*";
    public static final String MIME_TYPE_VIDEO = "video/*";
    public static final String MIME_TYPE_APP = "application/*";

    public static final String HIDDEN_PREFIX = ".";

    /**
     * Gets the extension of a file name, like ".png" or ".jpg".
     *
     * @param uri
     * @return Extension including the dot("."); "" if there is no extension;
     * null if uri was null.
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }

    /**
     * @return True if Uri is a MediaStore Uri.
     * @author paulburke
     */
    public static boolean isMediaUri(Uri uri) {
        return "media".equalsIgnoreCase(uri.getAuthority());
    }

    /**
     * Convert File into Uri.
     *
     * @param file
     * @return uri
     */
    public static Uri getUri(File file) {
        if (file != null) {
            return Uri.fromFile(file);
        }
        return null;
    }

    /**
     * Returns the path only (without file name).
     *
     * @param file
     * @return
     */
    public static File getPathWithoutFilename(File file) {
        if (file != null) {
            if (file.isDirectory()) {
                // no file to be split off. Return everything
                return file;
            } else {
                String filename = file.getName();
                String filepath = file.getAbsolutePath();

                // Construct path without file name.
                String pathwithoutname = filepath.substring(0,
                        filepath.length() - filename.length());
                if (pathwithoutname.endsWith("/")) {
                    pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
                }
                return new File(pathwithoutname);
            }
        }
        return null;
    }

    /**
     * @return The MIME type for the given file.
     */
    public static String getMimeType(File file) {

        String extension = getExtension(file.getName());

        if (extension.length() > 0)
            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));

        return "application/octet-stream";
    }

    /**
     * @return The MIME type for the give Uri.
     */
    public static String getMimeType(Context context, Uri uri) {
        File file = new File(getPath(context, uri));
        return getMimeType(file);
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is {@link LocalStorageProvider}.
     * @author paulburke
     */
    public static boolean isLocalStorageDocument(Uri uri) {
        return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     * @author paulburke
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     * @author paulburke
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);

                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * Get a file path from a Uri. This will quickGet the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     * @see #isLocal(String)
     * @see #getFile(Context, Uri)
     */
    public static String getPath(final Context context, final Uri uri) {

        if (DEBUG)
            Log.d(TAG + " File -",
                    "Authority: " + uri.getAuthority() +
                            ", Fragment: " + uri.getFragment() +
                            ", Port: " + uri.getPort() +
                            ", Query: " + uri.getQuery() +
                            ", Scheme: " + uri.getScheme() +
                            ", Host: " + uri.getHost() +
                            ", Segments: " + uri.getPathSegments().toString()
            );
        // DocumentProvider
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

//                if ("primary".equalsIgnoreCase(type)) {
//                    return Environment.getExternalStorageDirectory() + "/" + split[1];
//                }
                return Environment.getExternalStorageDirectory() + "/" + split[1];

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                try {
                    final String id = DocumentsContract.getDocumentId(uri);
                    Log.d(TAG, "getPath: id= " + id);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }catch (Exception e){
                    e.printStackTrace();
                    List<String> segments = uri.getPathSegments();
                    if(segments.size() > 1) {
                        String rawPath = segments.get(1);
                        if(!rawPath.startsWith("/")){
                            return rawPath.substring(rawPath.indexOf("/"));
                        }else {
                            return rawPath;
                        }
                    }
                }
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Convert Uri into File, if possible.
     *
     * @return file A local file that the Uri was pointing to, or null if the
     * Uri is unsupported or pointed to a remote resource.
     * @author paulburke
     * @see #getPath(Context, Uri)
     */
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }

    /**
     * Get the file size in a human-readable string.
     *
     * @param size
     * @return
     * @author paulburke
     */
    public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

    /**
     * Attempt to retrieve the thumbnail of given File from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param file
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, File file) {
        return getThumbnail(context, getUri(file), getMimeType(file));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri) {
        return getThumbnail(context, uri, getMimeType(context, uri));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @param mimeType
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
        if (DEBUG)
            Log.d(TAG, "Attempting to quickGet thumbnail");

        if (!isMediaUri(uri)) {
            Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
            return null;
        }

        Bitmap bm = null;
        if (uri != null) {
            final ContentResolver resolver = context.getContentResolver();
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, null, null, null, null);
                if (cursor.moveToFirst()) {
                    final int id = cursor.getInt(0);
                    if (DEBUG)
                        Log.d(TAG, "Got thumb ID: " + id);

                    if (mimeType.contains("video")) {
                        bm = MediaStore.Video.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Video.Thumbnails.MINI_KIND,
                                null);
                    } else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
                        bm = MediaStore.Images.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Images.Thumbnails.MINI_KIND,
                                null);
                    }
                }
            } catch (Exception e) {
                if (DEBUG)
                    Log.e(TAG, "getThumbnail", e);
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }
        return bm;
    }

    /**
     * File and folder comparator. TODO Expose sorting option method
     *
     * @author paulburke
     */
    public static Comparator<File> sComparator = new Comparator<File>() {
        @Override
        public int compare(File f1, File f2) {
            // Sort alphabetically by lower case, which is much cleaner
            return f1.getName().toLowerCase().compareTo(
                    f2.getName().toLowerCase());
        }
    };

    /**
     * File (not directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sFileFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return files only (not directories) and skip hidden files
            return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Folder (directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sDirFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return directories only and skip hidden directories
            return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Get the Intent for selecting content to be used in an Intent Chooser.
     *
     * @return The intent for opening a file with Intent.createChooser()
     * @author paulburke
     */
    public static Intent createGetContentIntent() {
        // Implicitly allow the user to select a particular kind of data
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // The MIME data type filter
        intent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        return intent;
    }
}


来源: stackexchange

问:
Individual column searching filter for js sourced data using DataTable.js
I need to have Individual column searching (select inputs) based filter,

I referred official tutorial on that topic

The below code doesn't generate the individual column filter drop down

Also, note this example demonstrates the use of initComplete, a callback function triggered when the table has fully loaded. Use of this callback isn't required in this example since the data is available in the table on load.

<!DOCTYPE html>

 <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />

 <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
 <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
 <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.6/css/buttons.dataTables.min.css">

```

答:
I would stick to initComplete option as it is triggered just once upon DataTable fully initialized and API methods can be called safely.

Though, I would code that feature in slightly less verbose manner:

const dataSet = [
  ["Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800"],
  ["Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750"],
  ["Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000"],
  ["Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060"],
  ["Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700"],
  ["Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000"],
  ["Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500"],
  ["Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900"],
  ["Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500"],
];

const dataTable = $('#example').DataTable({
    data: dataSet,
    dom: 't',
    columns: ['Name', 'Job Title', 'Location', 'Id', 'Hire Date', 'Salary'].map(header => ({
        title: header
      })),
    initComplete: function () {
      //purge existing
 if exists
      $('#example tfoot').remove();
      //append new footer to the table
      $('#example').append('

');
      //iterate through table columns
      this.api().columns().every(function () {
        //append <select> node to each column footer inserting
        //current column().index() as a "colindex" attribute
        $('#example tfoot tr').append(`<th><select colindex="${this.index()}"></select></th>`);
        //grab unique sorted column entries and translate those into <option> nodes
        const options = this.data().unique().sort().toArray().reduce((options, item) => options += `<option value="${item}">${item}</option>`, '<option value=""></option>');
        //append options to corresponding <select>
        $(`#example tfoot th:eq(${this.index()}) select`).append(options);
      });
    }
  });

$('#example').on('change', 'tfoot select', function (event) {
  //use "colindex" attribute value to search corresponding column for selected option value
  dataTable.column($(event.target).attr('colindex')).search($(event.target).val()).draw();
})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!doctype html>
<html>
<head>
  <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
  <table id="example"></table>
</body>
</html></code>```

ContentLicense: CC BY-SA 4.0

Body:
I would stick to initComplete option as it is triggered just once upon DataTable fully initialized and API methods can be called safely.

Though, I would code that feature in slightly less verbose manner:

const dataSet = [
  ["Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800"],
  ["Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750"],
  ["Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000"],
  ["Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060"],
  ["Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700"],
  ["Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000"],
  ["Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500"],
  ["Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900"],
  ["Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500"],
];

const dataTable = $('#example').DataTable({
    data: dataSet,
    dom: 't',
    columns: ['Name', 'Job Title', 'Location', 'Id', 'Hire Date', 'Salary'].map(header => ({
        title: header
      })),
    initComplete: function () {
      //purge existing <tfoot> if exists
      $('#example tfoot').remove();
      //append new footer to the table
      $('#example').append('<tfoot><tr></tr></tfoot>');
      //iterate through table columns
      this.api().columns().every(function () {
        //append <select> node to each column footer inserting
        //current column().index() as a "colindex" attribute
        $('#example tfoot tr').append(`<th><select colindex="${this.index()}"></select></th>`);
        //grab unique sorted column entries and translate those into <option> nodes
        const options = this.data().unique().sort().toArray().reduce((options, item) => options += `<option value="${item}">${item}</option>`, '<option value=""></option>');
        //append options to corresponding <select>
        $(`#example tfoot th:eq(${this.index()}) select`).append(options);
      });
    }
  });

$('#example').on('change', 'tfoot select', function (event) {
  //use "colindex" attribute value to search corresponding column for selected option value
  dataTable.column($(event.target).attr('colindex')).search($(event.target).val()).draw();
})

<!doctype html>
<html>
<head>
  <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
  <table id="example"></table>
</body>
</html>


问:
Mongoose validation err: Invalid schema configuration
Trying to model a relationship between collections by embedding documents
but when validating in the schema and setting "required" to True, here comes the err

once I comment the required in genre object in movies schema the problem is solved
but I want the validation

```<code>const Movie = mongoose.model(
  'Movies',
  new mongoose.Schema({
    title: {
      type: String,
      required: true,
      trim: true,
      minlength: 1,
      maxlength: 255
    },
    numberInStock: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    dailyRentalRate: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    genre: genreSchema
    required: true
  })
);

const genreSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minlength: 5,
    maxlength: 50
  }
});

</code>```

TypeError: Invalid schema configuration: True is not a valid type at path required

答:
Please share full code.

Maybe the main reason is that u not used

```<code>const Movie = mongoose.model(
  'Movies',
  new mongoose.Schema({
    title: {
      type: String,
      required: true,
      trim: true,
      minlength: 1,
      maxlength: 255
    },
    numberInStock: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    dailyRentalRate: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    genre: {
        ref: 'SchemaName',
        required: true
    },
  })
);
</code>```

You can do this like this.

Body:
Trying to model a relationship between collections by embedding documents
but when validating in the schema and setting "required" to True, here comes the err

once I comment the required in genre object in movies schema the problem is solved
but I want the validation

const Movie = mongoose.model(
  'Movies',
  new mongoose.Schema({
    title: {
      type: String,
      required: true,
      trim: true,
      minlength: 1,
      maxlength: 255
    },
    numberInStock: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    dailyRentalRate: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    genre: genreSchema
    required: true
  })
);

const genreSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minlength: 5,
    maxlength: 50
  }
});

TypeError: Invalid schema configuration: True is not a valid type at path required

Body:
Please share full code.

Maybe the main reason is that u not used

const Movie = mongoose.model(
  'Movies',
  new mongoose.Schema({
    title: {
      type: String,
      required: true,
      trim: true,
      minlength: 1,
      maxlength: 255
    },
    numberInStock: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    dailyRentalRate: {
      type: Number,
      required: true,
      min: 0,
      max: 255
    },
    genre: {
        ref: 'SchemaName',
        required: true
    },
  })
);

You can do this like this.


问:
Why does Sliver App Bar's flexibleSpace parameter have to take a Widget with a const constructor?
I am trying to build a custom scroll view which contains a sliver app bar to achieve something similar to what's shown here:

https://medium.com/@diegoveloper/flutter-collapsing-toolbar-sliver-app-bar-14b858e87abe

However I want to have the word Search and below it I want 3 IconButtons Evenly spaced, when the page (CustomScrollView) is scrolled, I want the 3 IconButtons to be pinned to the top of the SliverAppBar and the Search Text to disappear...

I Tried to achieve the above via the following code:

```<code> class SearchPage extends StatelessWidget {

      const SearchPage();

      @override
      Widget build(BuildContext context) {
        return CustomScrollView(slivers: <Widget>[
        const SliverAppBar(
        pinned: true,
            expandedHeight: 250.0,
            flexibleSpace: _buildSliverAppBarFlex(),
            );
      }

       Widget _buildSliverAppBarFlex() {
        return Container(
            child: Column(
              children: <Widget>[
                Text("Search", style: TextStyle(fontSize: 24.0,
                    color: Colors.white,
                    fontWeight: FontWeight.bold)),
                Row(children: <Widget>[
                  IconButton(icon: Icon(Icons.flight)),
                  IconButton(icon: Icon(Icons.hotel)),
                  IconButton(icon: Icon(Icons.drive_eta))
                ])
              ],
            )
        );
      }
    }
</code>```

However I get a warning that flexibleSpace must take a const constructor widget and that the _buildSilverAppBarFlex Widget I've made is not - I cannot add const or final to it either... Any ideas how I can achieve what I want?

答:
The warning comes because you are using const ahead of your SliverAppBar, remove this, and warning will be gone.

So, instead of this

```<code>const SliverAppBar(...)
</code>```

Use this.

```<code>SliverAppBar(...)
</code>```

If you want to use const there, make sure your FlexibleSpaceBar is also a const then.

Body:
I am trying to build a custom scroll view which contains a sliver app bar to achieve something similar to what's shown here:

https://medium.com/@diegoveloper/flutter-collapsing-toolbar-sliver-app-bar-14b858e87abe

However I want to have the word Search and below it I want 3 IconButtons Evenly spaced, when the page (CustomScrollView) is scrolled, I want the 3 IconButtons to be pinned to the top of the SliverAppBar and the Search Text to disappear...

I Tried to achieve the above via the following code:

 class SearchPage extends StatelessWidget {

      const SearchPage();

      @override
      Widget build(BuildContext context) {
        return CustomScrollView(slivers: <Widget>[
        const SliverAppBar(
        pinned: true,
            expandedHeight: 250.0,
            flexibleSpace: _buildSliverAppBarFlex(),
            );
      }

       Widget _buildSliverAppBarFlex() {
        return Container(
            child: Column(
              children: <Widget>[
                Text("Search", style: TextStyle(fontSize: 24.0,
                    color: Colors.white,
                    fontWeight: FontWeight.bold)),
                Row(children: <Widget>[
                  IconButton(icon: Icon(Icons.flight)),
                  IconButton(icon: Icon(Icons.hotel)),
                  IconButton(icon: Icon(Icons.drive_eta))
                ])
              ],
            )
        );
      }
    }

However I get a warning that flexibleSpace must take a const constructor widget and that the _buildSilverAppBarFlex Widget I've made is not - I cannot add const or final to it either... Any ideas how I can achieve what I want?

Body:
The warning comes because you are using const ahead of your SliverAppBar, remove this, and warning will be gone.

So, instead of this

const SliverAppBar(...)

Use this.

SliverAppBar(...)

If you want to use const there, make sure your FlexibleSpaceBar is also a const then.


问:
objective c interface access
this my first interface in a.h file.

```<code>@interface EventRow : NSObject
{
NSString *title;
NSString *photo;
NSString *description;

NSMutableArray *photoArray;
}
@property (nonatomic , retain) NSString *title;
@property (nonatomic , retain) NSString *photo;
@property (nonatomic , retain) NSString *description;

@property (nonatomic , retain) NSMutableArray *photoArray;

@end
</code>```

in the same file second

```<code>@interface PhotoRow : NSObject
{
//NSString *image;

NSMutableArray *imageArray;
}
@property (nonatomic , retain) NSMutableArray *imageArray;

@end
</code>```

Now every object of "PhotoRow" with filled array(imageArray) stored into the "photoArray" array in EventRow's object.

Now I want to count the total elements of "imageArray" . But getting problem in access it through the EventRow's object.

any suggestions ?

Thanks..

答:
If I understand you correctly, your photoArray variable in your EventRow class contains PhotoRow objects. You can count the objects in the PhotoRows imageArray variable like so:

```<code>int someIndex = 0;
[((PhotoRow*)[myEventRow.photoArray objectAtIndex:someIndex]).imageArray count];
</code>```

ContentLicense: CC BY-SA 3.0

Title: objective c interface access

Body:
this my first interface in a.h file.

@interface EventRow : NSObject
{
NSString *title;
NSString *photo;
NSString *description;

NSMutableArray *photoArray;
}
@property (nonatomic , retain) NSString *title;
@property (nonatomic , retain) NSString *photo;
@property (nonatomic , retain) NSString *description;

@property (nonatomic , retain) NSMutableArray *photoArray;

@end

in the same file second

@interface PhotoRow : NSObject
{
//NSString *image;

NSMutableArray *imageArray;
}
@property (nonatomic , retain) NSMutableArray *imageArray;

@end

Now every object of "PhotoRow" with filled array(imageArray) stored into the "photoArray" array in EventRow's object.

Now I want to count the total elements of "imageArray" . But getting problem in access it through the EventRow's object.

any suggestions ?

Thanks..

Body:
If I understand you correctly, your photoArray variable in your EventRow class contains PhotoRow objects. You can count the objects in the PhotoRows imageArray variable like so:

int someIndex = 0;
[((PhotoRow*)[myEventRow.photoArray objectAtIndex:someIndex]).imageArray count];


问:
Collection view inside table view
I have the following problem.
In my project I have a table view with multiple sections and one row in every section. Inside row I have a collection view.
Collection view items count depending on section in which the collection is located.But I do not understand how to access section number when I call func numberOfItemsInSection for collection view.

Here is my code:

ViewController.swift

```<code>func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
</code>```

TableCell.swift

```<code>func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //TODO ?????? How can i get here section of table view
}
</code>```

Thanks!

答:
Create an array in UITableViewCell subclass and use that array in collectionview datasource methods

```<code>class CustomCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
    var collectionData = [String]()

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return collectionData.count
    }
}
</code>```

In tableView cellForRowAt method assign value to the array and reload colletion view

```<code>override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as? CustomCell
    cell?.collectionData = []//assign data here based on indexPath.section
    cell?.collectionView.reloadData()
    return cell!
}
</code>```

Title: Collection view inside table view

Body:
I have the following problem.
In my project I have a table view with multiple sections and one row in every section. Inside row I have a collection view.
Collection view items count depending on section in which the collection is located.But I do not understand how to access section number when I call func numberOfItemsInSection for collection view.

Here is my code:

ViewController.swift

func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}

TableCell.swift

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //TODO ?????? How can i get here section of table view
}

Thanks!

Body:
Create an array in UITableViewCell subclass and use that array in collectionview datasource methods

class CustomCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
    var collectionData = [String]()

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return collectionData.count
    }
}

In tableView cellForRowAt method assign value to the array and reload colletion view

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as? CustomCell
    cell?.collectionData = []//assign data here based on indexPath.section
    cell?.collectionView.reloadData()
    return cell!
}


问:
I have installed TensorFlow in my Windows but I get an Error when I try to import it in my Jupyter Notebook
import tensorflow as tf

ModuleNotFoundError                       Traceback (most recent call last)
ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'

ImportError                               Traceback (most recent call last)
ImportError: numpy.core.multiarray failed to import

The above exception was the direct cause of the following exception:

SystemError                               Traceback (most recent call last)
~\AppData\Local\Continuum\anaconda3\lib\importlib_bootstrap.py in _find_and_load(name, import_)

SystemError:  returned a result with an error set

ImportError                               Traceback (most recent call last)
ImportError: numpy.core._multiarray_umath failed to import

ImportError                               Traceback (most recent call last)
ImportError: numpy.core.umath failed to import

答:
This happens because jupyter is not picking the tensorflow installed in that particular environment.

Solution for the above is:

```<code>conda activate <your-env>
conda install jupyter
pip install tensorflow
jupyter notebook
</code>```

This should work fine now, as you have installed jupyter using the conda within the environment.

Also, I can see in your post that there is problem with numpy.
As a precaution do:

```<code>pip install -U numpy
</code>```

or reinstall after uninstall

```<code>pip uninstall numpy
pip install numpy
</code>```

or the 3rd way:

```<code>pip install --ignore-installed numpy
</code>```

Remember to do after activating your environment.

This should sort it

Body:
This happens because jupyter is not picking the tensorflow installed in that particular environment.

Solution for the above is:

conda activate <your-env>
conda install jupyter
pip install tensorflow
jupyter notebook

This should work fine now, as you have installed jupyter using the conda within the environment.

Also, I can see in your post that there is problem with numpy.
As a precaution do:

pip install -U numpy

or reinstall after uninstall

pip uninstall numpy
pip install numpy

or the 3rd way:

pip install --ignore-installed numpy

Remember to do after activating your environment.

This should sort it


问:
How to format a number to a string in javascript
I'm working with Stripe Checkout, and feed the amount as a number like so 11999. How can I show this number as a string like $119.99?

I tried new Intl.NumberFormat('en-IN', { currency: 'USD' }).format(11999)

But it's show as $ 11,999

I tried http://numeraljs.com as well, but same issue. Any one have an idea?

答:
You can do it in couple of ways.

First way is to parse it as a number and than divide it by 100 but that has a downside if your number has more than 2 decimal numbers.

```<code>let format = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

format.format(parseFloat(11999)/100);
</code>```

If your number has more decimal points you can do something like:

```<code>let numberOfDigits = 2;
format.format(parseFloat(11999)/numberOfDigits*10);
</code>```

Body:
You can do it in couple of ways.

First way is to parse it as a number and than divide it by 100 but that has a downside if your number has more than 2 decimal numbers.

let format = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

format.format(parseFloat(11999)/100);

If your number has more decimal points you can do something like:

let numberOfDigits = 2;
format.format(parseFloat(11999)/numberOfDigits*10);


问:
Least repeating chararcter in a string
I'm trying to find the least repeating character in a string ,it works for some input but it fails for some input.

```<code>Map<Character, Integer> map = new HashMap<Character, Integer> ();

    String s = "abcdabcdabcdacd";
    char[] chars = s.toCharArray();

    for (Character ch: chars) {
        if (map.containsKey(ch)) {
            map.put(ch, map.get(ch) + 1);
        } else {
            map.put(ch, 1);
        }
    }

    Set<Character> keys = map.keySet();

    for (Character ch: keys) {
        if (map.get(ch) ==1) {
            System.out.println(ch + " ");
        }
    }
</code>```

I expect the output to be b but it doesn't show anything.
If i give aabaa as the input then it shows b and that's correct.

答:
The reason your code doesn't work the way you would want it to is because your last code block is only printing if the character is being repeated once and only once:

```<code>for (Character ch: keys) {
    if (map.get(ch) ==1) {
        System.out.println(ch + " ");
    }
</code>```

However by using the Collections.min method we can find the lowest map value which we can then use to find the character it belongs to from map keys. Here is the complete code with context:

```<code>/**
 * @return an array of Character objects that have occured the
 * least amount of times in the given {@code String} parameter.
 * <i>Note that all whitespaces found within the {@code String} will be ignored </i>
 */
public static Character[] getLeastRepeatingCharacters(String text) {

    Map<Character, Integer> map = new HashMap<Character, Integer> ();
    /*
     * Remove all whitespaces from the text as we don't
     * want to include them in our comparison oprations
     */
    text = text.replaceAll("\\s+","");

    for (Character ch : text.toCharArray()) {
        if (map.containsKey(ch)) {
            map.put(ch, map.get(ch) + 1);
        }
        else if (ch != '\0') {
            map.put(ch, 1);
        }
    }
    /*
     * Get map value that occurs the least amount of times
     */
    int leastOccuranceValue = Collections.min(map.values());
    java.util.List<Character> leastOccurances = new java.util.ArrayList<>();
    /*
     * Iterate through the map, find all characters that have
     * occured the least amount of times and add them to a list
     */
    for (java.util.Map.Entry<Character, Integer> entry : map.entrySet()) {
        if (entry.getValue().equals(leastOccuranceValue)) {
            leastOccurances.add(entry.getKey());
        }
    }
    return leastOccurances.toArray(new Character[0]);
}

public static void main(String[] args) {

    String text = "abcdabcdabcdacd";
    Character[] leastRepeating = getLeastRepeatingCharacters(text);

    String log = "Array of charactes that repeated the least amount of times in text '%s':%n%s";
    System.out.printf(log, text, Arrays.toString(leastRepeating));
}
</code>```

Output:

Your string sample:

```<code>Array of charactes that repeated the least amount of times in text 'abcdabcdabcdacd ':
[b]
</code>```

String sample provided by Stultuske:

```<code>Array of charactes that repeated the least amount of times in text 'kambcxdabcdalbcdacd ':
[x, k, l, m]
</code>```

Title: Least repeating chararcter in a string

Body:
I'm trying to find the least repeating character in a string ,it works for some input but it fails for some input.

Map<Character, Integer> map = new HashMap<Character, Integer> ();

    String s = "abcdabcdabcdacd";
    char[] chars = s.toCharArray();

    for (Character ch: chars) {
        if (map.containsKey(ch)) {
            map.put(ch, map.get(ch) + 1);
        } else {
            map.put(ch, 1);
        }
    }

    Set<Character> keys = map.keySet();

    for (Character ch: keys) {
        if (map.get(ch) ==1) {
            System.out.println(ch + " ");
        }
    }

I expect the output to be b but it doesn't show anything.
If i give aabaa as the input then it shows b and that's correct.

Body:
The reason your code doesn't work the way you would want it to is because your last code block is only printing if the character is being repeated once and only once:

for (Character ch: keys) {
    if (map.get(ch) ==1) {
        System.out.println(ch + " ");
    }

However by using the Collections.min method we can find the lowest map value which we can then use to find the character it belongs to from map keys. Here is the complete code with context:

/**
 * @return an array of Character objects that have occured the
 * least amount of times in the given {@code String} parameter.
 * <i>Note that all whitespaces found within the {@code String} will be ignored </i>
 */
public static Character[] getLeastRepeatingCharacters(String text) {

    Map<Character, Integer> map = new HashMap<Character, Integer> ();
    /*
     * Remove all whitespaces from the text as we don't
     * want to include them in our comparison oprations
     */
    text = text.replaceAll("\\s+","");

    for (Character ch : text.toCharArray()) {
        if (map.containsKey(ch)) {
            map.put(ch, map.get(ch) + 1);
        }
        else if (ch != '\0') {
            map.put(ch, 1);
        }
    }
    /*
     * Get map value that occurs the least amount of times
     */
    int leastOccuranceValue = Collections.min(map.values());
    java.util.List<Character> leastOccurances = new java.util.ArrayList<>();
    /*
     * Iterate through the map, find all characters that have
     * occured the least amount of times and add them to a list
     */
    for (java.util.Map.Entry<Character, Integer> entry : map.entrySet()) {
        if (entry.getValue().equals(leastOccuranceValue)) {
            leastOccurances.add(entry.getKey());
        }
    }
    return leastOccurances.toArray(new Character[0]);
}

public static void main(String[] args) {

    String text = "abcdabcdabcdacd";
    Character[] leastRepeating = getLeastRepeatingCharacters(text);

    String log = "Array of charactes that repeated the least amount of times in text '%s':%n%s";
    System.out.printf(log, text, Arrays.toString(leastRepeating));
}

Output:

Your string sample:

Array of charactes that repeated the least amount of times in text 'abcdabcdabcdacd ':
[b]

String sample provided by Stultuske:

Array of charactes that repeated the least amount of times in text 'kambcxdabcdalbcdacd ':
[x, k, l, m]


问:
MSVC 1 bit enum type equals -1 and equality test fails
I have defined a bitfield of enum types to match a set of bits in an embedded system. I'm trying to write a test harness in MSVC for the code, but comparing what should be equal values fails.

The definition looks like this:

typedef enum { SERIAL, PARALLEL } MODE_e;
typedef union {
    struct {
        TYPE_e      Type    : 1;    // 1
        POSITION_e  1Pos    : 1;    // 2
        POSITION_e  2Pos    : 1;    // 3
        bool        Enable  : 1;    // 4
        NET_e       Net     : 1;    // 5
        TYPE_e      Type    : 1;    // 6
        bool        En      : 1;    // 7
        TIME_e      Time    : 3;    // 8-10
        MODE_e      Mode    : 1;    // 11
        bool        TestEn  : 1;    // 12
        bool        DelayEn : 1;    // 13
        MODE_e      Mode    : 1;    // 14
        bool        xEn     : 1;    // 15
        MODE_e      yMode   : 1;    // 16
        bool        zEnable : 1;    // 17
    } Bits;
    uint32_t Word;
} BITS_t;
```
<p>Later the following comparison fails:</p>
<pre class="lang-none prettyprint-override"><code>Store.Bits.Mode = PARALLEL;
if (store.Bits.Mode == PARALLEL)
    ...
</code>```

I examined the Mode bool in the debugger, and it looked odd. The value of Mode is -1.

It's as if MSVC considers the value to be a two's complement number, but 1 bit wide, so 0b1 is decimal -1. The enum sets PARALLEL to 1, so the two do not match.

The comparison works fine on the embedded side using LLVM or GCC.

Which behavior is correct? I assume GCC and LLVM have better support for the C standards than MSVC in areas such as bit fields. More importantly, can I work around this difference without making major changes to the embedded code?

答:
Dissecting this in detail, you have the following problems:

There is no guarantee that Type : 1 is the MSB or LSB. Generally, there are no guarantees of the bit-field layout in memory at all.

As mentioned in other answers, enumeration variables (unlike enumeration constants) have implementation-defined size. Meaning that you can't know their size, portably. In addition, if the size is something which isn't the same as either int or _Bool, the compiler need not support it at all.

Enums are most often a signed integer type. And when you create a bit-field of size 1 with a signed type, nobody including the standard knows what it means. Is it the sign bit you intend to store there or is it data?

The size of what the C standard calls "storage unit" inside the bit-field, is unspecified. Typically it is alignment-based. The C standard does guarantee that if you have several bit-fields of the same type trailing each other, they must be merged into the same storage unit (if there is room). For different types, there are no such guarantees.

It is fairly common that when you go from one type like POSITION_e to a different type bool, the compiler places them in different storage units. In practice meaning that there's a high risk of padding bit insertion whenever this happens. Lots of mainstream compilers do in fact behave just like that.

In addition, a struct or union may contain padding bytes anywhere.

In addition, there is the endianess problem.

Conclusion: bit-fields cannot be used in programs that need any form of portability. They cannot be used for the purpose of memory mapping.

Also, you really don't need all these abstraction layers - it's a simple dip-switch, not a space shuttle! :)

Solution:

I would strongly recommend to drop all of this in favour for a plain uint32_t. You can mask individual bits with plain integer constants:

```<code>#define DIP_TYPE (1u << 31)
#define DIP_POS   (1u << 30)
...

uint32_t dipswitch = ...;
bool actuator_active = dipswitch & DIP_TYPE; // read
dipswitch |= DIP_POS;     // write
</code>```

This is massively portable, well-defined, standardized, MISRA-C compliant - you can even port it between different endianess architectures. It solves all of the above mentioned problems.

Body:
I have defined a bitfield of enum types to match a set of bits in an embedded system. I'm trying to write a test harness in MSVC for the code, but comparing what should be equal values fails.

The definition looks like this:

typedef enum { SERIAL, PARALLEL } MODE_e;
typedef union {
    struct {
        TYPE_e      Type    : 1;    // 1
        POSITION_e  1Pos    : 1;    // 2
        POSITION_e  2Pos    : 1;    // 3
        bool        Enable  : 1;    // 4
        NET_e       Net     : 1;    // 5
        TYPE_e      Type    : 1;    // 6
        bool        En      : 1;    // 7
        TIME_e      Time    : 3;    // 8-10
        MODE_e      Mode    : 1;    // 11
        bool        TestEn  : 1;    // 12
        bool        DelayEn : 1;    // 13
        MODE_e      Mode    : 1;    // 14
        bool        xEn     : 1;    // 15
        MODE_e      yMode   : 1;    // 16
        bool        zEnable : 1;    // 17
    } Bits;
    uint32_t Word;
} BITS_t;

Later the following comparison fails:

Store.Bits.Mode = PARALLEL;
if (store.Bits.Mode == PARALLEL)
    ...

I examined the Mode bool in the debugger, and it looked odd. The value of Mode is -1.

It's as if MSVC considers the value to be a two's complement number, but 1 bit wide, so 0b1 is decimal -1. The enum sets PARALLEL to 1, so the two do not match.

The comparison works fine on the embedded side using LLVM or GCC.

Which behavior is correct? I assume GCC and LLVM have better support for the C standards than MSVC in areas such as bit fields. More importantly, can I work around this difference without making major changes to the embedded code?

Body:
Dissecting this in detail, you have the following problems:

There is no guarantee that Type : 1 is the MSB or LSB. Generally, there are no guarantees of the bit-field layout in memory at all.

As mentioned in other answers, enumeration variables (unlike enumeration constants) have implementation-defined size. Meaning that you can't know their size, portably. In addition, if the size is something which isn't the same as either int or _Bool, the compiler need not support it at all.

Enums are most often a signed integer type. And when you create a bit-field of size 1 with a signed type, nobody including the standard knows what it means. Is it the sign bit you intend to store there or is it data?

The size of what the C standard calls "storage unit" inside the bit-field, is unspecified. Typically it is alignment-based. The C standard does guarantee that if you have several bit-fields of the same type trailing each other, they must be merged into the same storage unit (if there is room). For different types, there are no such guarantees.

It is fairly common that when you go from one type like POSITION_e to a different type bool, the compiler places them in different storage units. In practice meaning that there's a high risk of padding bit insertion whenever this happens. Lots of mainstream compilers do in fact behave just like that.

In addition, a struct or union may contain padding bytes anywhere.

In addition, there is the endianess problem.

Conclusion: bit-fields cannot be used in programs that need any form of portability. They cannot be used for the purpose of memory mapping.

Also, you really don't need all these abstraction layers - it's a simple dip-switch, not a space shuttle! :)

Solution:

I would strongly recommend to drop all of this in favour for a plain uint32_t. You can mask individual bits with plain integer constants:

#define DIP_TYPE (1u << 31)
#define DIP_POS   (1u << 30)
...

uint32_t dipswitch = ...;
bool actuator_active = dipswitch & DIP_TYPE; // read
dipswitch |= DIP_POS;     // write

This is massively portable, well-defined, standardized, MISRA-C compliant - you can even port it between different endianess architectures. It solves all of the above mentioned problems.


问:
How to click the element from the table Search by specific text
How to click on element search by text within table. I have tried some code but its not working.

HTML:

```<code><td _ngcontent-c8="" class="align-middle cursorPoint" tabindex="0">Shelton</td>
</code>```

I want to click on this
 which having text Shelton in it.

答:
The desired element is an Angular element so to locate and click() the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following Locator Strategy:

xpath 1:

```<code>new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[@class='align-middle cursorPoint' and text()='Shelton']"))).click();
</code>```

xpath 2:

```<code>new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[text()='Shelton']"))).click();
</code>```

Update

To achieve the same in a step-wise manner:

```<code>WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[@class='align-middle cursorPoint' and text()='Shelton']")));
elem.click();
</code>```

Body:
How to click on element search by text within table. I have tried some code but its not working.

HTML:

Shelton

I want to click on this
 which having text Shelton in it.

Body:
The desired element is an Angular element so to locate and click() the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following Locator Strategy:

xpath 1:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[@class='align-middle cursorPoint' and text()='Shelton']"))).click();

xpath 2:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[text()='Shelton']"))).click();

Update

To achieve the same in a step-wise manner:

WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[@class='align-middle cursorPoint' and text()='Shelton']")));
elem.click();


问:
MySQL - ORDER BY Rand() always gives the same result
I have a query that selects and groups random records like below:

```<code>SELECT PRDT_CODE FROM (
    SELECT * FROM CTGR
    INNER JOIN PRDT on PRDT.PRDT_CTGR = CTGR.CTGR_CODE AND PRDT.PRDT_STUS = 'A'
    INNER JOIN PFIL on PFIL.PFIL_PRDT = PRDT.PRDT_CODE AND PFIL.PFIL_MAIN = 1
    ORDER BY RAND()
) A
GROUP BY CTGR_CODE
LIMIT 4;
</code>```

The same query is executed on MySQL Workbench and PhpMyAdmin.

The result set gotten from the Workbench is completely random (which is something I want). On the other hand, PhpMyAdmin returns the same result set despite the ORDER BY RAND() keyword is being used.

Any idea why this is happening?

EDIT

Results in Workbench:

1st run:

2nd run:

Results in PMA:

1st run:

2nd run:

Expected output: the result set from Workbench;

Actual output: the result set from PMA

答:
Try using the order by in the out query</p>

```<code>SELECT * FROM (
    SELECT * FROM CTGR
    INNER JOIN PRDT on PRDT.PRDT_CTGR = CTGR.CTGR_CODE AND PRDT.PRDT_STUS = 'A'
    INNER JOIN PFIL on PFIL.PFIL_PRDT = PRDT.PRDT_CODE AND PFIL.PFIL_MAIN = 1
    ) A
GROUP BY CTGR_CODE
ORDER BY RAND()
LIMIT 4;
</code>```

Body:
I have a query that selects and groups random records like below:

SELECT PRDT_CODE FROM (
    SELECT * FROM CTGR
    INNER JOIN PRDT on PRDT.PRDT_CTGR = CTGR.CTGR_CODE AND PRDT.PRDT_STUS = 'A'
    INNER JOIN PFIL on PFIL.PFIL_PRDT = PRDT.PRDT_CODE AND PFIL.PFIL_MAIN = 1
    ORDER BY RAND()
) A
GROUP BY CTGR_CODE
LIMIT 4;

The same query is executed on MySQL Workbench and PhpMyAdmin.

The result set gotten from the Workbench is completely random (which is something I want). On the other hand, PhpMyAdmin returns the same result set despite the ORDER BY RAND() keyword is being used.

Any idea why this is happening?

EDIT

Results in Workbench:

1st run:

2nd run:

Results in PMA:

1st run:

2nd run:

Expected output: the result set from Workbench;

Actual output: the result set from PMA

Body:
Try using the order by in the out query

SELECT * FROM (
    SELECT * FROM CTGR
    INNER JOIN PRDT on PRDT.PRDT_CTGR = CTGR.CTGR_CODE AND PRDT.PRDT_STUS = 'A'
    INNER JOIN PFIL on PFIL.PFIL_PRDT = PRDT.PRDT_CODE AND PFIL.PFIL_MAIN = 1
    ) A
GROUP BY CTGR_CODE
ORDER BY RAND()
LIMIT 4;


问:
Adding data to db that comes from DTOs
I have entities and related DTOs which are used to transfer data from DB (Entity framework 6) to different layers of my web api. Here is the code:

```<code>    public class Dish
    {
        public int DishId { get; set; }

        [Required]
        [Index(IsUnique = true)]
        [StringLength(400)]
        public string Name { get; set; }

        public string Description { get; set; }

        public double PreparationTime { get; set; }

        public string Photo { get; set; }

        public virtual ICollection<Category> Categories { get; set; } = new List<Category>();

        public virtual ICollection<Ingredient> Ingredients { get; set; } = new List<Ingredient>();

        public virtual ICollection<IngredientAmount> IngredientAmounts { get; set; } = new List<IngredientAmount>();

        public virtual ICollection<RecipeUnit> RecipeUnits { get; set; } = new List<RecipeUnit>();
    }
</code>```

```<code>public class DishDetailedDTO: IDishDTO
    {
        public int DishId { get; set; }

        [Required]
        [StringLength(400)]
        public string Name { get; set; }

        public string Description { get; set; }

        public double PreparationTime { get; set; }

        public string Photo { get; set; }

        public List<CategoryDTO> Categories { get; set; }

        public List<IngredientDetailedDTO> Ingredients { get; set; }

        public List<IngredientAmountDTO> IngredientAmounts { get; set; }

        public List<RecipeUnitDTO> RecipeUnits { get; set; }

    }
</code>```

```<code>public class Category
    {
        public int CategoryId { get; set; }

        [Required]
        [Index(IsUnique = true)]
        [StringLength(20)]
        public string Name { get; set; }

        public virtual ICollection<Dish> Dishes { get; set; } = new List<Dish>();
    }
</code>```

```<code>    public class CategoryDTO: ICategoryDTO
    {
        public int CategoryId { get; set; }

        [Required]
        [StringLength(20)]
        public string Name { get; set; }
    }
</code>```

The problem comes in when I try to add new Dish object which navigation property(lets say category) alredy exists in database. Generaly I get DishDTO from somewhere (frontend), then use automapper to map it to Dish and then add this Dish to context. Here is the reproduction of the problem in smaller scale:

```<code>        static void Main(string[] args)
        {
            Mapper.Initialize(x=>
            {
                x.CreateMap<Dish, DishDTO>();
                x.CreateMap<Dish, DishDetailedDTO>();
                x.CreateMap<Dish, DishAvailableIngredientsDTO>();
                x.CreateMap<DishDTO, Dish>();
                x.CreateMap<DishDetailedDTO, Dish>();
                x.CreateMap<DishAvailableIngredientsDTO, Dish>();
                x.CreateMap<Category, CategoryDTO>();
                x.CreateMap<CategoryDTO, Category>();
                x.CreateMap<Ingredient, IngredientDetailedDTO>();
                x.CreateMap<Ingredient, IngredientDTO>();
                x.CreateMap<IngredientDTO, Ingredient>();
                x.CreateMap<IngredientDetailedDTO, Ingredient>();
                x.CreateMap<IngredientAmount, IngredientAmountDTO>();
                x.CreateMap<IngredientAmountDTO, IngredientAmount>();
                x.CreateMap<RecipeUnit, RecipeUnitDTO>();
                x.CreateMap<RecipeUnitDTO, RecipeUnit>();
            });

            var context = new EFDbContext();

            var dish = new DishDetailedDTO()
            {
                Name = "SomeName",
                Categories = new List<CategoryDTO>
                {
                   new CategoryDTO()
                   {
                       Name = "Breakfast"
                   }
                }
            };

            context.Dishes.Add(Mapper.Map<Dish>(dish));
            context.SaveChanges();

            Console.ReadLine();

        }
</code>```

Then I've got exception

```<code>SqlException: Cannot insert duplicate key row in object 'dbo.Categories' with unique index 'IX_Name'. The duplicate key value is (Breakfast).
The statement has been terminated.
</code>```

答:
the design of your Dish model is wrong, one Dish can have multiple Categories and one Category can have multiple Dishes which makes it a many to many relation. To handle this situation you need to add another model something like:-

```<code>public class DishCategoryMapping
{
    public int Id { get; set; }
    public int DishId { get; set; }
    public int CategoryId { get; set; }

    //navigation properties
}
</code>```

then your dish model will look like

```<code>public class Dish
{
    public int DishId { get; set; }
    public virtual ICollection<DishCategoryMapping> DishCategoryMappings { get; set; }

    //other properties
}
</code>```

then you will insert a row for each category that a dish has in the DishCategoryMapping table.

Title: Adding data to db that comes from DTOs

Body:
I have entities and related DTOs which are used to transfer data from DB (Entity framework 6) to different layers of my web api. Here is the code:

    public class Dish
    {
        public int DishId { get; set; }

        [Required]
        [Index(IsUnique = true)]
        [StringLength(400)]
        public string Name { get; set; }

        public string Description { get; set; }

        public double PreparationTime { get; set; }

        public string Photo { get; set; }

        public virtual ICollection<Category> Categories { get; set; } = new List<Category>();

        public virtual ICollection<Ingredient> Ingredients { get; set; } = new List<Ingredient>();

        public virtual ICollection<IngredientAmount> IngredientAmounts { get; set; } = new List<IngredientAmount>();

        public virtual ICollection<RecipeUnit> RecipeUnits { get; set; } = new List<RecipeUnit>();
    }

public class DishDetailedDTO: IDishDTO
    {
        public int DishId { get; set; }

        [Required]
        [StringLength(400)]
        public string Name { get; set; }

        public string Description { get; set; }

        public double PreparationTime { get; set; }

        public string Photo { get; set; }

        public List<CategoryDTO> Categories { get; set; }

        public List<IngredientDetailedDTO> Ingredients { get; set; }

        public List<IngredientAmountDTO> IngredientAmounts { get; set; }

        public List<RecipeUnitDTO> RecipeUnits { get; set; }

    }

public class Category
    {
        public int CategoryId { get; set; }

        [Required]
        [Index(IsUnique = true)]
        [StringLength(20)]
        public string Name { get; set; }

        public virtual ICollection<Dish> Dishes { get; set; } = new List<Dish>();
    }

    public class CategoryDTO: ICategoryDTO
    {
        public int CategoryId { get; set; }

        [Required]
        [StringLength(20)]
        public string Name { get; set; }
    }

The problem comes in when I try to add new Dish object which navigation property(lets say category) alredy exists in database. Generaly I get DishDTO from somewhere (frontend), then use automapper to map it to Dish and then add this Dish to context. Here is the reproduction of the problem in smaller scale:

        static void Main(string[] args)
        {
            Mapper.Initialize(x=>
            {
                x.CreateMap<Dish, DishDTO>();
                x.CreateMap<Dish, DishDetailedDTO>();
                x.CreateMap<Dish, DishAvailableIngredientsDTO>();
                x.CreateMap<DishDTO, Dish>();
                x.CreateMap<DishDetailedDTO, Dish>();
                x.CreateMap<DishAvailableIngredientsDTO, Dish>();
                x.CreateMap<Category, CategoryDTO>();
                x.CreateMap<CategoryDTO, Category>();
                x.CreateMap<Ingredient, IngredientDetailedDTO>();
                x.CreateMap<Ingredient, IngredientDTO>();
                x.CreateMap<IngredientDTO, Ingredient>();
                x.CreateMap<IngredientDetailedDTO, Ingredient>();
                x.CreateMap<IngredientAmount, IngredientAmountDTO>();
                x.CreateMap<IngredientAmountDTO, IngredientAmount>();
                x.CreateMap<RecipeUnit, RecipeUnitDTO>();
                x.CreateMap<RecipeUnitDTO, RecipeUnit>();
            });

            var context = new EFDbContext();

            var dish = new DishDetailedDTO()
            {
                Name = "SomeName",
                Categories = new List<CategoryDTO>
                {
                   new CategoryDTO()
                   {
                       Name = "Breakfast"
                   }
                }
            };

            context.Dishes.Add(Mapper.Map<Dish>(dish));
            context.SaveChanges();

            Console.ReadLine();

        }

Then I've got exception

SqlException: Cannot insert duplicate key row in object 'dbo.Categories' with unique index 'IX_Name'. The duplicate key value is (Breakfast).
The statement has been terminated.

Body:
the design of your Dish model is wrong, one Dish can have multiple Categories and one Category can have multiple Dishes which makes it a many to many relation. To handle this situation you need to add another model something like:-

public class DishCategoryMapping
{
    public int Id { get; set; }
    public int DishId { get; set; }
    public int CategoryId { get; set; }

    //navigation properties
}

then your dish model will look like

public class Dish
{
    public int DishId { get; set; }
    public virtual ICollection<DishCategoryMapping> DishCategoryMappings { get; set; }

    //other properties
}

then you will insert a row for each category that a dish has in the DishCategoryMapping table.


问:
Trying to response Amazon's Captcha with scrapy, strange behavior on spider generator
I'm creating a crawler to Amazon for study reason, but it is being caught by their captcha.
So I have made a captcha solver, but I'm having trouble to response the captcha form.
The problem is that if I put a yeild FormRequest in the method, it seems to not be called.

class Havaianas2Spider(scrapy.Spider):
    name = 'coleta_dados_grafo'
    rank_path = sorted([x for x in os.listdir('scraps') if 'links_base' in x], reverse=True)[0]
    lista_links = pd.read_csv('scraps/' + rank_path)
    start_urls = lista_links['links'].values
    custom_settings = {'FEED_URI': "scraps/produtos_%(time)s.csv",
                       'FEED_FORMAT': 'csv'}
    final_path = '/?th=1&psc=1'

    def base_path_get(self, response):
        dp_idx = response.request.url.find('/dp/') + 4
        base_path = response.request.url[:dp_idx]
        return base_path

    def solve_captcha(self, response, origin_method):
        self.logger.info('SOLVING CAPTCHA!')
        captcha_url = response.xpath('//div[@class="a-row a-text-center"]/img/@src').extract_first()
        img = load_url(captcha_url)
        captcha_string = break_captcha(img)
        img.save('C:/Users/Bruno Aquino/Documents/ecom_scraper/amazon_scraper/amazon_scraper/captchas/{}.jpg'.format(
            captcha_string))
        yield FormRequest.from_response(response,
                                        formdata={'field-keywords': captcha_string},
                                        callback=origin_method)

    def verify_if_captcha(self, response):
        captcha_url = response.xpath('//div[@class="a-row a-text-center"]/img/@src').extract_first()

        if captcha_url:
            self.logger.info('PAGE {} GOT BY CAPTCHA!'.format(response.request.url))
            return True
        else:
            return False

    def parse(self, response):

        captcha = self.verify_if_captcha(response)

        if captcha:
            self.solve_captcha(response, self.parse)

        else:
            base_path = self.base_path_get(response)

            asin_colors = response.xpath('//div[@id="cerberus-data-metrics"]/@data-asin').extract() +\
            [x[4:14] for x in response.xpath('//li[contains(@id,"color_name_")]/@data-dp-url').extract() if '/dp/' in x]

            for asin in asin_colors:
                new_path = base_path + asin + self.final_path

                if asin:
                    yield scrapy.Request(
                        response.urljoin(new_path),
                        callback=self.parse_l2)
```

<p>below the Amazon's captcha form</p>

<pre class="lang-html prettyprint-override"><code><form method="get" action="/errors/validateCaptcha" name="">
                            <input type=hidden name="amzn" value="Xnnhl7YtGcH60X2yPaN7eA==" /><input type=hidden name="amzn-r" value="/Capodarte-Chinelo-Preto-38/dp/B07N13Q5F2/?th=1&psc=1" />
                            <div class="a-row a-spacing-large">
                                <div class="a-box">
                                    <div class="a-box-inner">
                                        <h4>Type the characters you see in this image:</h4>
                                        <div class="a-row a-text-center">
                                            <img src="https://images-na.ssl-images-amazon.com/captcha/yniigayf/Captcha_kbknwlcmvm.jpg">
                                        </div>
                                        <div class="a-row a-spacing-base">
                                            <div class="a-row">
                                                <div class="a-column a-span6">
                                                    <label for="captchacharacters">Type characters</label>
                                                </div>
                                                <div class="a-column a-span6 a-span-last a-text-right">
                                                    Try different image
                                                </div>
                                            </div>
                                            <input autocomplete="off" spellcheck="false" id="captchacharacters" name="field-keywords" class="a-span12" autocapitalize="off" autocorrect="off" type="text">
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div class="a-section a-spacing-extra-large">

                                <div class="a-row">
                                    <span class="a-button a-button-primary a-span12">
                                        <span class="a-button-inner">
                                            <button type="submit" class="a-button-text">Continue shopping</button>
                                        </span>
                                    </span>
                                </div>

                            </div>
                        </form>
</code>```

I put two logs into the code.

The first on inside the verify_if_captcha:

self.logger.info('PAGE {} GOT BY CAPTCHA!'.format(response.request.url))
```

<p>This one is printed</p>

<p>The second inside the solve_captcha:</p>

<pre class="lang-py prettyprint-override"><code>self.logger.info('SOLVING CAPTCHA!')
</code>```

This one is never printed

Can some one help me, please?

答:
Currently, your form request object is never returned to Scrapy for handling.

Replace self.solve_captcha(response, self.parse) by yield from self.solve_captcha(response, self.parse).

Body:
I'm creating a crawler to Amazon for study reason, but it is being caught by their captcha.
So I have made a captcha solver, but I'm having trouble to response the captcha form.
The problem is that if I put a yeild FormRequest in the method, it seems to not be called.

class Havaianas2Spider(scrapy.Spider):
    name = 'coleta_dados_grafo'
    rank_path = sorted([x for x in os.listdir('scraps') if 'links_base' in x], reverse=True)[0]
    lista_links = pd.read_csv('scraps/' + rank_path)
    start_urls = lista_links['links'].values
    custom_settings = {'FEED_URI': "scraps/produtos_%(time)s.csv",
                       'FEED_FORMAT': 'csv'}
    final_path = '/?th=1&psc=1'

    def base_path_get(self, response):
        dp_idx = response.request.url.find('/dp/') + 4
        base_path = response.request.url[:dp_idx]
        return base_path

    def solve_captcha(self, response, origin_method):
        self.logger.info('SOLVING CAPTCHA!')
        captcha_url = response.xpath('//div[@class="a-row a-text-center"]/img/@src').extract_first()
        img = load_url(captcha_url)
        captcha_string = break_captcha(img)
        img.save('C:/Users/Bruno Aquino/Documents/ecom_scraper/amazon_scraper/amazon_scraper/captchas/{}.jpg'.format(
            captcha_string))
        yield FormRequest.from_response(response,
                                        formdata={'field-keywords': captcha_string},
                                        callback=origin_method)

    def verify_if_captcha(self, response):
        captcha_url = response.xpath('//div[@class="a-row a-text-center"]/img/@src').extract_first()

        if captcha_url:
            self.logger.info('PAGE {} GOT BY CAPTCHA!'.format(response.request.url))
            return True
        else:
            return False

    def parse(self, response):

        captcha = self.verify_if_captcha(response)

        if captcha:
            self.solve_captcha(response, self.parse)

        else:
            base_path = self.base_path_get(response)

            asin_colors = response.xpath('//div[@id="cerberus-data-metrics"]/@data-asin').extract() +\
            [x[4:14] for x in response.xpath('//li[contains(@id,"color_name_")]/@data-dp-url').extract() if '/dp/' in x]

            for asin in asin_colors:
                new_path = base_path + asin + self.final_path

                if asin:
                    yield scrapy.Request(
                        response.urljoin(new_path),
                        callback=self.parse_l2)

below the Amazon's captcha form

<form method="get" action="/errors/validateCaptcha" name="">
                            <input type=hidden name="amzn" value="Xnnhl7YtGcH60X2yPaN7eA==" /><input type=hidden name="amzn-r" value="/Capodarte-Chinelo-Preto-38/dp/B07N13Q5F2/?th=1&psc=1" />

Type the characters you see in this image:

                                                    Type characters

                                                    Try different image

                                            <input autocomplete="off" spellcheck="false" id="captchacharacters" name="field-keywords" class="a-span12" autocapitalize="off" autocorrect="off" type="text">

                                            <button type="submit" class="a-button-text">Continue shopping</button>

                        </form>

I put two logs into the code.

The first on inside the verify_if_captcha:

self.logger.info('PAGE {} GOT BY CAPTCHA!'.format(response.request.url))

This one is printed

The second inside the solve_captcha:

self.logger.info('SOLVING CAPTCHA!')

This one is never printed

Can some one help me, please?


问:
How to get an AWS EC2 instance ID from within that EC2 instance?
How can I find out the instance id of an ec2 instance from within the ec2 instance?

答:
For a Windows instance:

```<code>(wget http://169.254.169.254/latest/meta-data/instance-id).Content
</code>```

or

```<code>(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId
</code>```

OwnerDisplayName: andy

Body:
For a Windows instance:

(wget http://169.254.169.254/latest/meta-data/instance-id).Content

or

(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId