问:
Design function so variables get assigned values without large if/else block
There must be a better way to do this:

```<code>def map_leds(self, i):
        if i[0] == 1:
            self.ledg_1_1.setVisible(True)
            self.ledr_1_1.setVisible(False)
        else:
            self.ledg_1_1.setVisible(False)
            self.ledr_1_1.setVisible(True)

###############################################

        if int(i[1]) == 1:
            self.ledg_1_2.setVisible(True)
            self.ledr_1_2.setVisible(False)
        else:
            self.ledg_1_2.setVisible(False)
            self.ledr_1_2.setVisible(True)

###############################################

        if int(i[2]) == 1:
            self.ledg_1_3.setVisible(True)
            self.ledr_1_3.setVisible(False)
        else:
            self.ledg_1_3.setVisible(False)
            self.ledr_1_3.setVisible(True)

###############################################

        if int(i[3]) == 1:
            self.ledg_2_1.setVisible(True)
            self.ledr_2_1.setVisible(False)
        else:
            self.ledg_2_1.setVisible(False)
            self.ledr_2_1.setVisible(True)

###############################################

        if int(i[4]) == 1:
            self.ledg_2_2.setVisible(True)
            self.ledr_2_2.setVisible(False)
        else:
            self.ledg_2_2.setVisible(False)
            self.ledr_2_2.setVisible(True)

###############################################

        if int(i[5]) == 1:
            self.ledg_2_3.setVisible(True)
            self.ledr_2_3.setVisible(False)
        else:
            self.ledg_2_3.setVisible(False)
            self.ledr_2_3.setVisible(True)

###############################################

        if int(i[6]) == 1:
            self.ledg_3_1.setVisible(True)
            self.ledr_3_1.setVisible(False)
        else:
            self.ledg_3_1.setVisible(False)
            self.ledr_3_1.setVisible(True)

###############################################

        if int(i[7]) == 1:
            self.ledg_3_2.setVisible(True)
            self.ledr_3_2.setVisible(False)
        else:
            self.ledg_3_2.setVisible(False)
            self.ledr_3_2.setVisible(True)

###############################################

if int(i[8]) == 1:
            self.ledg_3_3.setVisible(True)
            self.ledr_3_3.setVisible(False)
        else:
            self.ledg_3_3.setVisible(False)
            self.ledr_3_3.setVisible(True)
</code>```

I have 9 LEDS, and I my function map_leds is fed an list of len 9 populated with 0s and 1s. If the first value is 1, the first LED should be green (this is a GUI, so an LED is actually a picture and I have to switch between both pictures, hence the "setVisible" function). If the first value is 0, then the LED (that should be displayed) is the red one. And so on for all the other values.

There must be a better way to actually do all this than have a huge if-else statement block, right?

答:
Maybe separate them into smaller functions?

```<code>def hand_ledg_1_1 (val):
    if val == 1:
        print("green")
        self.ledg_1_1.setVisible(True)
        self.ledr_1_1.setVisible(False)
    else:
        print("red")
        self.ledg_1_1.setVisible(False)
        self.ledr_1_1.setVisible(True)

def hand_ledg_1_2 (val):
    if int(val) == 1:
        self.ledg_1_2.setVisible(True)
        self.ledr_1_2.setVisible(False)
    else:
        self.ledg_1_2.setVisible(False)
        self.ledr_1_2.setVisible(True)

def hand_ledg_1_3 (val):
    if int(val) == 1:
        self.ledg_1_3.setVisible(True)
        self.ledr_1_3.setVisible(False)
    else:
        self.ledg_1_3.setVisible(False)
        self.ledr_1_3.setVisible(True)

def hand_ledg_2_1 (val):
    if int(val) == 1:
        self.ledg_2_1.setVisible(True)
        self.ledr_2_1.setVisible(False)
    else:
        self.ledg_2_1.setVisible(False)
        self.ledr_2_1.setVisible(True)

def hand_ledg_2_2 (val):
    if int(val) == 1:
        self.ledg_2_2.setVisible(True)
        self.ledr_2_2.setVisible(False)
    else:
        self.ledg_2_2.setVisible(False)
        self.ledr_2_2.setVisible(True)

def hand_ledg_2_3 (val):
    if int(val) == 1:
        self.ledg_2_3.setVisible(True)
        self.ledr_2_3.setVisible(False)
    else:
        self.ledg_2_3.setVisible(False)
        self.ledr_2_3.setVisible(True)

def hand_ledg_3_1 (val):
    if int(val) == 1:
        self.ledg_3_1.setVisible(True)
        self.ledr_3_1.setVisible(False)
    else:
        self.ledg_3_1.setVisible(False)
        self.ledr_3_1.setVisible(True)

def hand_ledg_3_2 (val):
    if int(val) == 1:
        self.ledg_3_2.setVisible(True)
        self.ledr_3_2.setVisible(False)
    else:
        self.ledg_3_2.setVisible(False)
        self.ledr_3_2.setVisible(True)

def hand_ledg_3_3 (val):
    if int(i[8]) == 1:
        print("green1")
        self.ledg_3_3.setVisible(True)
        self.ledr_3_3.setVisible(False)
    else:
        print("red1")
        self.ledg_3_3.setVisible(False)
        self.ledr_3_3.setVisible(True)

def map_leds(self, i):
    hand_ledg_1_1(i[0])
    hand_ledg_1_2(i[1])
    hand_ledg_1_3(i[2])
    hand_ledg_2_1(i[3])
    hand_ledg_2_2(i[4])
    hand_ledg_2_3(i[5])
    hand_ledg_3_1(i[6])
    hand_ledg_3_2(i[7])
    hand_ledg_3_3(i[8])
</code>```

It's easier to read at least

Body:
There must be a better way to do this:

def map_leds(self, i):
        if i[0] == 1:
            self.ledg_1_1.setVisible(True)
            self.ledr_1_1.setVisible(False)
        else:
            self.ledg_1_1.setVisible(False)
            self.ledr_1_1.setVisible(True)

###############################################

        if int(i[1]) == 1:
            self.ledg_1_2.setVisible(True)
            self.ledr_1_2.setVisible(False)
        else:
            self.ledg_1_2.setVisible(False)
            self.ledr_1_2.setVisible(True)

###############################################

        if int(i[2]) == 1:
            self.ledg_1_3.setVisible(True)
            self.ledr_1_3.setVisible(False)
        else:
            self.ledg_1_3.setVisible(False)
            self.ledr_1_3.setVisible(True)

###############################################

        if int(i[3]) == 1:
            self.ledg_2_1.setVisible(True)
            self.ledr_2_1.setVisible(False)
        else:
            self.ledg_2_1.setVisible(False)
            self.ledr_2_1.setVisible(True)

###############################################

        if int(i[4]) == 1:
            self.ledg_2_2.setVisible(True)
            self.ledr_2_2.setVisible(False)
        else:
            self.ledg_2_2.setVisible(False)
            self.ledr_2_2.setVisible(True)

###############################################

        if int(i[5]) == 1:
            self.ledg_2_3.setVisible(True)
            self.ledr_2_3.setVisible(False)
        else:
            self.ledg_2_3.setVisible(False)
            self.ledr_2_3.setVisible(True)

###############################################

        if int(i[6]) == 1:
            self.ledg_3_1.setVisible(True)
            self.ledr_3_1.setVisible(False)
        else:
            self.ledg_3_1.setVisible(False)
            self.ledr_3_1.setVisible(True)

###############################################

        if int(i[7]) == 1:
            self.ledg_3_2.setVisible(True)
            self.ledr_3_2.setVisible(False)
        else:
            self.ledg_3_2.setVisible(False)
            self.ledr_3_2.setVisible(True)

###############################################

if int(i[8]) == 1:
            self.ledg_3_3.setVisible(True)
            self.ledr_3_3.setVisible(False)
        else:
            self.ledg_3_3.setVisible(False)
            self.ledr_3_3.setVisible(True)

I have 9 LEDS, and I my function map_leds is fed an list of len 9 populated with 0s and 1s. If the first value is 1, the first LED should be green (this is a GUI, so an LED is actually a picture and I have to switch between both pictures, hence the "setVisible" function). If the first value is 0, then the LED (that should be displayed) is the red one. And so on for all the other values.

There must be a better way to actually do all this than have a huge if-else statement block, right?

Body:
Maybe separate them into smaller functions?

def hand_ledg_1_1 (val):
    if val == 1:
        print("green")
        self.ledg_1_1.setVisible(True)
        self.ledr_1_1.setVisible(False)
    else:
        print("red")
        self.ledg_1_1.setVisible(False)
        self.ledr_1_1.setVisible(True)

def hand_ledg_1_2 (val):
    if int(val) == 1:
        self.ledg_1_2.setVisible(True)
        self.ledr_1_2.setVisible(False)
    else:
        self.ledg_1_2.setVisible(False)
        self.ledr_1_2.setVisible(True)

def hand_ledg_1_3 (val):
    if int(val) == 1:
        self.ledg_1_3.setVisible(True)
        self.ledr_1_3.setVisible(False)
    else:
        self.ledg_1_3.setVisible(False)
        self.ledr_1_3.setVisible(True)

def hand_ledg_2_1 (val):
    if int(val) == 1:
        self.ledg_2_1.setVisible(True)
        self.ledr_2_1.setVisible(False)
    else:
        self.ledg_2_1.setVisible(False)
        self.ledr_2_1.setVisible(True)

def hand_ledg_2_2 (val):
    if int(val) == 1:
        self.ledg_2_2.setVisible(True)
        self.ledr_2_2.setVisible(False)
    else:
        self.ledg_2_2.setVisible(False)
        self.ledr_2_2.setVisible(True)

def hand_ledg_2_3 (val):
    if int(val) == 1:
        self.ledg_2_3.setVisible(True)
        self.ledr_2_3.setVisible(False)
    else:
        self.ledg_2_3.setVisible(False)
        self.ledr_2_3.setVisible(True)

def hand_ledg_3_1 (val):
    if int(val) == 1:
        self.ledg_3_1.setVisible(True)
        self.ledr_3_1.setVisible(False)
    else:
        self.ledg_3_1.setVisible(False)
        self.ledr_3_1.setVisible(True)

def hand_ledg_3_2 (val):
    if int(val) == 1:
        self.ledg_3_2.setVisible(True)
        self.ledr_3_2.setVisible(False)
    else:
        self.ledg_3_2.setVisible(False)
        self.ledr_3_2.setVisible(True)

def hand_ledg_3_3 (val):
    if int(i[8]) == 1:
        print("green1")
        self.ledg_3_3.setVisible(True)
        self.ledr_3_3.setVisible(False)
    else:
        print("red1")
        self.ledg_3_3.setVisible(False)
        self.ledr_3_3.setVisible(True)

def map_leds(self, i):
    hand_ledg_1_1(i[0])
    hand_ledg_1_2(i[1])
    hand_ledg_1_3(i[2])
    hand_ledg_2_1(i[3])
    hand_ledg_2_2(i[4])
    hand_ledg_2_3(i[5])
    hand_ledg_3_1(i[6])
    hand_ledg_3_2(i[7])
    hand_ledg_3_3(i[8])

It's easier to read at least


来源: stackexchange

问:
Can I disable sign-up in Azure AD B2C?
Can I disable sign-up in Azure AD B2C? In other words, I don't want customers to sign up accounts by themselves, I want it to be done only by admin in Azure. Thanks.</p>

答:
Built-in Policies

Yes, only define a Sign-in policy.

Do not define a Sign-up or Sign-in policy nor a Sign-up policy.

Custom Policies

The problem with a sign-in only policy is you only have basic UI customization options.  You do not get the full set of features as described here.

With custom policies, you can define a Sign-Up/Sign-In policy and then disable the Sign-Up portion.  This allows for the same level if UI customization as described here.

Hide the Sign-Up link via CSS

Remove <Item Key="SignUpTarget">SignUpWithLogonUsernameExchange</Item> from your TechnicalProfile

<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Username-NoSignUp">
    <DisplayName>Local Account Signin</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>

        <Item Key="setting.operatingMode">Username</Item>
        <Item Key="ContentDefinitionReferenceId">api.selfasserted-ext-local</Item>
        <Item Key="language.button_continue">Login</Item>
    </Metadata>
    ...
</TechnicalProfile>
```

ContentLicense: CC BY-SA 3.0

Title: Can I disable sign-up in Azure AD B2C?

Body:
Built-in Policies

Yes, only define a Sign-in policy.

Do not define a Sign-up or Sign-in policy nor a Sign-up policy.

Custom Policies

The problem with a sign-in only policy is you only have basic UI customization options.  You do not get the full set of features as described here.

With custom policies, you can define a Sign-Up/Sign-In policy and then disable the Sign-Up portion.  This allows for the same level if UI customization as described here.

Hide the Sign-Up link via CSS

Remove <Item Key="SignUpTarget">SignUpWithLogonUsernameExchange</Item> from your TechnicalProfile

<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Username-NoSignUp">
    <DisplayName>Local Account Signin</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <!-- Want to disable sign-up on unified policy -->
        <!-- <Item Key="SignUpTarget">SignUpWithLogonUsernameExchange</Item> -->
        <Item Key="setting.operatingMode">Username</Item>
        <Item Key="ContentDefinitionReferenceId">api.selfasserted-ext-local</Item>
        <Item Key="language.button_continue">Login</Item>
    </Metadata>
    ...
</TechnicalProfile>


问:
Retrofit uploading a picture
I'm using Retrofit v.2.2.0 to upload a picture to my server but the server returns a null value stating no image has been uploaded. The logs shows the image is uploaded and the file name is correct when uploaded. What can be the problem yet it works in postman?

UploadProfilePicture.java

```<code>public class UploadProfilePicture extends ContextWrapper {

private GetOnUpload onUpload;
private File imageFile,filesDir,file;
private Uri fileUri;
private String profilePic = "profile_pic";
private String fileName;
private ParcelFileDescriptor parcelFileDescriptor;
private FileDescriptor fileDescriptor;
private  Bitmap profileImage;
private OutputStream os;
private OkHttpLogClientAPI okHttpLogClientAPI;
private GetOnUpload mInterfaceService;

public UploadProfilePicture(Context base) {
    super(base);

    okHttpLogClientAPI = new OkHttpLogClientAPI(getBaseContext());

    mInterfaceService = okHttpLogClientAPI.logger().create(GetOnUpload.class);

}

public void uploadPic(Uri fileUri,String fileName, final OnSetUploadProfilePic setOnUpload) {
    //Build Req estBodies for the map object and a MultipartBody.Part to encapsulate the prof_pic_drawer

    this.fileUri = fileUri;
    this.fileName = fileName;
    try {
        getBitmapFromUri();
    } catch (IOException e) {
        e.printStackTrace();
    }
    file = persistImage();

    RequestBody finalRequestBody = builder.build();
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("multipart/form-data"), getBytesFromBitmap(profileImage));

    // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part body =
            MultipartBody.Part.createFormData("file", "avatar.jpg", requestFile);
        Call<ResponseUserModel> call = mInterfaceService.upload(body);

        call.enqueue(new Callback<ResponseUserModel>() {

            @Override
            public void onResponse(Call<Response> call, Response<Response> response) {

                if (response.isSuccessful()) {
                    setOnUpload.uploadMessage(response.body());

                } else {
                    Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();
                }

            }

            @Override
            public void onFailure(Call<Response> call, Throwable t) {

                Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();

            }
        });
    }
}

public static byte[] getBytesFromBitmap(Bitmap bitmap) {
    if (bitmap!=null) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        return stream.toByteArray();
    }
    return null;
}

private MultipartBody.Part prepareFilePart() {

    //TODO: Use FileUtils to get the actual file by uri

    try {
        getBitmapFromUri();
        file = persistImage();

    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        RequestBody requestFile = RequestBody.create(
                MediaType.parse(getBaseContext().getContentResolver().getType(fileUri)), file);
            return MultipartBody.Part.createFormData("file", file.getName(), requestFile);

    } catch (NullPointerException e) {

        Toast.makeText(getBaseContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();

        return null;
    }

}

private RequestBody createPartFromString(String descriptionString) {
    return RequestBody.create(MultipartBody.FORM, descriptionString);
}

private void getBitmapFromUri() throws IOException {
    profileImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), fileUri);
}

private File persistImage() {
    filesDir = getFilesDir();
     imageFile = new File(filesDir, fileName + ".jpg");

    OutputStream os;
    try {
        os = new FileOutputStream(imageFile);
        profileImage.compress(Bitmap.CompressFormat.JPEG, 70, os);
        os.flush();
        os.close();
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
    }

    return imageFile;
}}
</code>```

GetOnUpload.java

```<code>public interface GetOnUpload {
 @Multipart
@POST(Constants.UPLOAD_URL)
Call<Response> upload(@Part MultipartBody.Part file);}
</code>```

Log

http://local.com/api/v1/avatar http/1.1
11-14 18:40:02.742 8851-9593/com.local.test D/OkHttp: Content-Type: multipart/form-data; boundary=d43da080-f2c3-4743-8cfd-9526cc0bd2f7
11-14 18:40:02.742 8851-9593/com.local.test D/OkHttp: Content-Length: 12424
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: --d43da080-f2c3-4743-8cfd-9526cc0bd2f7
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: Content-Disposition: form-data; name="file"; filename="avatar.jpg"
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: Content-Type: multipart/form-data
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: Content-Length: 12201
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp:
11-14 18:40:02.744 8851-9593/com.local.test D/OkHttp: --d43da080-f2c3-4743-8cfd-9526cc0bd2f7--
11-14 18:40:02.744 8851-9593/com.local.test D/OkHttp: --> END POST (12424-byte body)

11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: <-- 200 OK http://local.com/api/v1/avatar (587ms)
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Server: nginx/1.10.3 (Ubuntu)
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Content-Type: application/json
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Transfer-Encoding: chunked
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Connection: keep-alive
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Cache-Control: no-cache, private
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Date: Tue, 14 Nov 2017 15:40:03 GMT
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: X-RateLimit-Limit: 60
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: X-RateLimit-Remaining: 59
11-14 18:40:03.333 8851-9593/com.local.test D/OkHttp: {"user":"Failed","status":"Image file not uploaded"}

答:
ImageFilePath

```<code>@SuppressLint("NewApi")
@TargetApi(Build.VERSION_CODES.KITKAT)
public class ImageFilePath {

    /**
     * Method for return file path of Gallery image
     *
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    static String nopath = "Select Video Only";

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) {

        // check here to KITKAT or new version
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

            // ExternalStorageProvider
            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];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // 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 nopath;
    }

    /**
     * Get the value of the data column for this Uri. This is <span id="IL_AD2"
     * class="IL_AD">useful</span> 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.
     */
    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()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return nopath;
    }

    /**
     * @param uri
     * The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    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.
     */
    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.
     */
    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());
    }
}
</code>```

ChooseImg

```<code>  private void openChooseImgDialog() {
        Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
        getIntent.setType("image/*");

        Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        pickIntent.setType("image/*");

        Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});

        startActivityForResult(chooserIntent, PICK_IMAGE);

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case PICK_IMAGE:
                if (resultCode == Activity.RESULT_OK) {
                    uri = data.getData();
                    File_Path = ImageFilePath.getPath(getActivity(), data.getData());

                    // File_Path = RealPathUtil.getRealPathFromURI_API19(getActivity(), data.getData());

                    //    String filename = uri.getLastPathSegment();

                    Log.d("displayfiletypes","****  "+data.getData() + "         "+File_Path);
                    tv_feedbackfilename.setText(File_Path.substring(File_Path.lastIndexOf("/")+1));

                    try {
                        Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
                        // Log.d(TAG, String.valueOf(bitmap));

                        // mImgView.setImageBitmap(bitmap);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(getActivity(), "Something Went Wrong", Toast.LENGTH_SHORT).show();
                }
                break;

        }
    }
</code>```

Interface

```<code>@Multipart
@POST("url")
Call<ResponseBody> add_feedback(@Part MultipartBody.Part file);
</code>```

Add this code in your Activity

```<code> Retrofit adapter = new Retrofit.Builder()
                    .baseUrl(Constandapi.ROOT_URL)
                    .build();

   RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);

            MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("your php file key", file.getName(), requestBody);
      Call<ResponseBody> adding_feedback = addfeedback.add_feedback(auth_key_sent, subjectstring_sent, feedbackmsg_sent, fileToUpload);

       adding_feedback.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful())
                {
                    progressDialog.dismiss();

                    String result = null;

                    try{
                        result = response.body().string();
                        Log.d("createddates","responce"+result);
                                           }catch (IOException e){
                        e.printStackTrace();
                    }catch (JSONException jsone){
                        jsone.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Toast.makeText(getActivity(), "Please try after sometime", Toast.LENGTH_SHORT).show();

                Log.d("printmessages","***  "+call.toString() + "  "+t.toString());
                progressDialog.dismiss();

            }
        });
</code>```

Title: Retrofit uploading a picture

Body:
I'm using Retrofit v.2.2.0 to upload a picture to my server but the server returns a null value stating no image has been uploaded. The logs shows the image is uploaded and the file name is correct when uploaded. What can be the problem yet it works in postman?

UploadProfilePicture.java

public class UploadProfilePicture extends ContextWrapper {

private GetOnUpload onUpload;
private File imageFile,filesDir,file;
private Uri fileUri;
private String profilePic = "profile_pic";
private String fileName;
private ParcelFileDescriptor parcelFileDescriptor;
private FileDescriptor fileDescriptor;
private  Bitmap profileImage;
private OutputStream os;
private OkHttpLogClientAPI okHttpLogClientAPI;
private GetOnUpload mInterfaceService;

public UploadProfilePicture(Context base) {
    super(base);

    okHttpLogClientAPI = new OkHttpLogClientAPI(getBaseContext());

    mInterfaceService = okHttpLogClientAPI.logger().create(GetOnUpload.class);

}

public void uploadPic(Uri fileUri,String fileName, final OnSetUploadProfilePic setOnUpload) {
    //Build Req estBodies for the map object and a MultipartBody.Part to encapsulate the prof_pic_drawer

    this.fileUri = fileUri;
    this.fileName = fileName;
    try {
        getBitmapFromUri();
    } catch (IOException e) {
        e.printStackTrace();
    }
    file = persistImage();

    RequestBody finalRequestBody = builder.build();
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("multipart/form-data"), getBytesFromBitmap(profileImage));

    // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part body =
            MultipartBody.Part.createFormData("file", "avatar.jpg", requestFile);
        Call<ResponseUserModel> call = mInterfaceService.upload(body);

        call.enqueue(new Callback<ResponseUserModel>() {

            @Override
            public void onResponse(Call<Response> call, Response<Response> response) {

                if (response.isSuccessful()) {
                    setOnUpload.uploadMessage(response.body());

                } else {
                    Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();
                }

            }

            @Override
            public void onFailure(Call<Response> call, Throwable t) {

                Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();

            }
        });
    }
}

public static byte[] getBytesFromBitmap(Bitmap bitmap) {
    if (bitmap!=null) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        return stream.toByteArray();
    }
    return null;
}

private MultipartBody.Part prepareFilePart() {

    //TODO: Use FileUtils to get the actual file by uri

    try {
        getBitmapFromUri();
        file = persistImage();

    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        RequestBody requestFile = RequestBody.create(
                MediaType.parse(getBaseContext().getContentResolver().getType(fileUri)), file);
            return MultipartBody.Part.createFormData("file", file.getName(), requestFile);

    } catch (NullPointerException e) {

        Toast.makeText(getBaseContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();

        return null;
    }

}

private RequestBody createPartFromString(String descriptionString) {
    return RequestBody.create(MultipartBody.FORM, descriptionString);
}

private void getBitmapFromUri() throws IOException {
    profileImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), fileUri);
}

private File persistImage() {
    filesDir = getFilesDir();
     imageFile = new File(filesDir, fileName + ".jpg");

    OutputStream os;
    try {
        os = new FileOutputStream(imageFile);
        profileImage.compress(Bitmap.CompressFormat.JPEG, 70, os);
        os.flush();
        os.close();
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
    }

    return imageFile;
}}

GetOnUpload.java

public interface GetOnUpload {
 @Multipart
@POST(Constants.UPLOAD_URL)
Call<Response> upload(@Part MultipartBody.Part file);}

Log

http://local.com/api/v1/avatar http/1.1
11-14 18:40:02.742 8851-9593/com.local.test D/OkHttp: Content-Type: multipart/form-data; boundary=d43da080-f2c3-4743-8cfd-9526cc0bd2f7
11-14 18:40:02.742 8851-9593/com.local.test D/OkHttp: Content-Length: 12424
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: --d43da080-f2c3-4743-8cfd-9526cc0bd2f7
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: Content-Disposition: form-data; name="file"; filename="avatar.jpg"
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: Content-Type: multipart/form-data
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp: Content-Length: 12201
11-14 18:40:02.743 8851-9593/com.local.test D/OkHttp:
11-14 18:40:02.744 8851-9593/com.local.test D/OkHttp: --d43da080-f2c3-4743-8cfd-9526cc0bd2f7--
11-14 18:40:02.744 8851-9593/com.local.test D/OkHttp: --> END POST (12424-byte body)

11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: <-- 200 OK http://local.com/api/v1/avatar (587ms)
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Server: nginx/1.10.3 (Ubuntu)
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Content-Type: application/json
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Transfer-Encoding: chunked
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Connection: keep-alive
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Cache-Control: no-cache, private
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: Date: Tue, 14 Nov 2017 15:40:03 GMT
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: X-RateLimit-Limit: 60
11-14 18:40:03.332 8851-9593/com.local.test D/OkHttp: X-RateLimit-Remaining: 59
11-14 18:40:03.333 8851-9593/com.local.test D/OkHttp: {"user":"Failed","status":"Image file not uploaded"}

Body:
ImageFilePath

@SuppressLint("NewApi")
@TargetApi(Build.VERSION_CODES.KITKAT)
public class ImageFilePath {

    /**
     * Method for return file path of Gallery image
     *
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    static String nopath = "Select Video Only";

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) {

        // check here to KITKAT or new version
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

            // ExternalStorageProvider
            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];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // 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 nopath;
    }

    /**
     * Get the value of the data column for this Uri. This is <span id="IL_AD2"
     * class="IL_AD">useful</span> 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.
     */
    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()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return nopath;
    }

    /**
     * @param uri
     * The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    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.
     */
    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.
     */
    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());
    }
}

ChooseImg

  private void openChooseImgDialog() {
        Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
        getIntent.setType("image/*");

        Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        pickIntent.setType("image/*");

        Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});

        startActivityForResult(chooserIntent, PICK_IMAGE);

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case PICK_IMAGE:
                if (resultCode == Activity.RESULT_OK) {
                    uri = data.getData();
                    File_Path = ImageFilePath.getPath(getActivity(), data.getData());

                    // File_Path = RealPathUtil.getRealPathFromURI_API19(getActivity(), data.getData());

                    //    String filename = uri.getLastPathSegment();

                    Log.d("displayfiletypes","****  "+data.getData() + "         "+File_Path);
                    tv_feedbackfilename.setText(File_Path.substring(File_Path.lastIndexOf("/")+1));

                    try {
                        Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
                        // Log.d(TAG, String.valueOf(bitmap));

                        // mImgView.setImageBitmap(bitmap);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(getActivity(), "Something Went Wrong", Toast.LENGTH_SHORT).show();
                }
                break;

        }
    }

Interface

@Multipart
@POST("url")
Call<ResponseBody> add_feedback(@Part MultipartBody.Part file);

Add this code in your Activity

 Retrofit adapter = new Retrofit.Builder()
                    .baseUrl(Constandapi.ROOT_URL)
                    .build();

   RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);

            MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("your php file key", file.getName(), requestBody);
      Call<ResponseBody> adding_feedback = addfeedback.add_feedback(auth_key_sent, subjectstring_sent, feedbackmsg_sent, fileToUpload);

       adding_feedback.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful())
                {
                    progressDialog.dismiss();

                    String result = null;

                    try{
                        result = response.body().string();
                        Log.d("createddates","responce"+result);
                                           }catch (IOException e){
                        e.printStackTrace();
                    }catch (JSONException jsone){
                        jsone.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Toast.makeText(getActivity(), "Please try after sometime", Toast.LENGTH_SHORT).show();

                Log.d("printmessages","***  "+call.toString() + "  "+t.toString());
                progressDialog.dismiss();

            }
        });


问:
What is the fastest way to generate a random integer in javascript?
Normally this is how you get a random number in javascript.

```<code>Math.random();
</code>```

However, this method seems to be inefficient when it comes to generating random integers.

Firstly, the random function has to generate a random decimal, like 0.1036098338663578, then it has to be multiplied to a suitable range (10.464593220502138). Finally, the floor function subtracts the decimals to produce the result (which in this case, 10).

```<code>var random_integer = Math.floor(Math.random()*101);
</code>```

Is there a faster way to generate random integers in javascript?

Edit1:

I am using this for creating a canvas HTML5 game. The FPS is about 50, and my code is pretty optimized, apart from generating a random number.

答:
i mostly use </p>

```<code>    var a = Math.floor(Math.random((number you'd like to be minimum, (number you'd like to be maximum) * (number you'd like to be maximum);
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Normally this is how you get a random number in javascript.

Math.random();

However, this method seems to be inefficient when it comes to generating random integers.

Firstly, the random function has to generate a random decimal, like 0.1036098338663578, then it has to be multiplied to a suitable range (10.464593220502138). Finally, the floor function subtracts the decimals to produce the result (which in this case, 10).

var random_integer = Math.floor(Math.random()*101);

Is there a faster way to generate random integers in javascript?

Edit1:

I am using this for creating a canvas HTML5 game. The FPS is about 50, and my code is pretty optimized, apart from generating a random number.

Body:
i mostly use

    var a = Math.floor(Math.random((number you'd like to be minimum, (number you'd like to be maximum) * (number you'd like to be maximum);


问:
Is it possible to hide a page in a PDF document using javascript?
Is it possible to hide a page in a PDF document using javascript?</p>

答:
If there is, it would be through the acrobat javascript API:

http://www.adobe.com/devnet/acrobat/javascript.html

ContentLicense: CC BY-SA 2.5


问:
React Router URL Throws Error With Parameter
I am trying to use react router to have dynamic profile pages, preferably having it in slashes rather than like a ? parameter wildcard in the URL. I'm looking for like /profile/{username}/ rather than /profile?user={username} if that makes sense.

Here's the route that I'm using to try and achieve this;

```<code><Route path="/profile/:name/" component={Profile}/>
</code>```

But when I try and go to this route as in `/profile/jeff/' or anything it returns a bundle.js (webpack'd) that is a blank HTML template, which is unexpected to be in the bundle.js and throws an error. Any idea's how I can fix this? Thanks.

Here is the bundle.js that gets returned;

```<code><html>
<body style="margin:0px; padding: 0px;">
    <link rel="stylesheet" href="styles.css">
    <link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
    <div id = "root" style="margin:0px; padding: 0px;"></div>
    <script src="bundle.js"></script>
</body>
</code>```

Profile component;

```<code>import React from 'react';
import styles from './profile.scss';
import astyles from './allpages.scss';

export default class Profile extends React.Component{
render(){

    console.log("hello!");

    const { match, location, history } = this.props

    console.log(location);
    console.log(match);
    console.log(history);

    return(
        <div className = {styles.borderContainer}>
            <p> {this.props.param.name} </p>
        </div>
    )
}
}
</code>```

Webpack config;

```<code>var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
require('style-loader');
require('css-loader');

const loaders = {
    css: {
        loader: 'css-loader'
    },
    postcss: {
        loader: 'postcss-loader',
        options: {
            plugins: (loader) => [
                autoprefixer({
                    browsers: ['last 2 versions']
                })
            ]
        }
    },
    sass: {
        loader: 'sass-loader',
        options: {
            indentedSyntax: true,
            includePaths: [path.resolve(__dirname, './src/app')]
        }
    }
}

module.exports = {
    context: __dirname,
    entry: './src/app/index.js',
    output: {
        path: __dirname + '/dist/',
        filename: 'bundle.js',
        libraryTarget: 'umd'
    },
    devtool: "sourceMap",
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',

                    // Could also be write as follow:
                    // use: 'css-loader?modules&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader'
                    use: [
                        {
                            loader: 'css-loader',
                            query: {
                                modules: true,
                                localIdentName: '[name]__[local]___[hash:base64:5]'
                            }
                        },
                        'postcss-loader'
                    ]
                }),
            },
            {
                test: /\.scss$/,
                exclude: /node_modules/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',

                    // Could also be write as follow:
                    // use: 'css-loader?modules&importLoader=2&sourceMap&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader'
                    use: [
                        {
                            loader: 'css-loader',
                            query: {
                                modules: true,
                                sourceMap: true,
                                importLoaders: 2,
                                localIdentName: '[name]__[local]___[hash:base64:5]'
                            }
                        },
                        'sass-loader'
                    ]
                }),
            },
        ],
    },
    plugins: [
        new ExtractTextPlugin('styles.css'),
    ],
}
</code>```

答:
When you request /profile/jeff/ you serve the index.html you posted, and presumably that is done for every resource that doesn't exist on your server (as a fallback). In the index.html you have the following script tag:

```<code><script src="bundle.js"></script>
</code>```

This is a relative path. You are actually requesting /profile/jeff/bundle.js at this point and because that doesn't exist, you end up serving the index.html as the bundle, which is problematic because it's not valid JavaScript.

You should always use /bundle.js regardless of the current URL. Similarly you'd always want /styles.css for your CSS.

```<code><link rel="stylesheet" href="/styles.css">
<script src="/bundle.js"></script>
</code>```

Body:
I am trying to use react router to have dynamic profile pages, preferably having it in slashes rather than like a ? parameter wildcard in the URL. I'm looking for like /profile/{username}/ rather than /profile?user={username} if that makes sense.

Here's the route that I'm using to try and achieve this;

<Route path="/profile/:name/" component={Profile}/>

But when I try and go to this route as in `/profile/jeff/' or anything it returns a bundle.js (webpack'd) that is a blank HTML template, which is unexpected to be in the bundle.js and throws an error. Any idea's how I can fix this? Thanks.

Here is the bundle.js that gets returned;

    <link rel="stylesheet" href="styles.css">
    <link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">

Profile component;

import React from 'react';
import styles from './profile.scss';
import astyles from './allpages.scss';

export default class Profile extends React.Component{
render(){

    console.log("hello!");

    const { match, location, history } = this.props

    console.log(location);
    console.log(match);
    console.log(history);

    return(

 {this.props.param.name}

    )
}
}

Webpack config;

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
require('style-loader');
require('css-loader');

const loaders = {
    css: {
        loader: 'css-loader'
    },
    postcss: {
        loader: 'postcss-loader',
        options: {
            plugins: (loader) => [
                autoprefixer({
                    browsers: ['last 2 versions']
                })
            ]
        }
    },
    sass: {
        loader: 'sass-loader',
        options: {
            indentedSyntax: true,
            includePaths: [path.resolve(__dirname, './src/app')]
        }
    }
}

module.exports = {
    context: __dirname,
    entry: './src/app/index.js',
    output: {
        path: __dirname + '/dist/',
        filename: 'bundle.js',
        libraryTarget: 'umd'
    },
    devtool: "sourceMap",
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',

                    // Could also be write as follow:
                    // use: 'css-loader?modules&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader'
                    use: [
                        {
                            loader: 'css-loader',
                            query: {
                                modules: true,
                                localIdentName: '[name]__[local]___[hash:base64:5]'
                            }
                        },
                        'postcss-loader'
                    ]
                }),
            },
            {
                test: /\.scss$/,
                exclude: /node_modules/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',

                    // Could also be write as follow:
                    // use: 'css-loader?modules&importLoader=2&sourceMap&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader'
                    use: [
                        {
                            loader: 'css-loader',
                            query: {
                                modules: true,
                                sourceMap: true,
                                importLoaders: 2,
                                localIdentName: '[name]__[local]___[hash:base64:5]'
                            }
                        },
                        'sass-loader'
                    ]
                }),
            },
        ],
    },
    plugins: [
        new ExtractTextPlugin('styles.css'),
    ],
}

Body:
When you request /profile/jeff/ you serve the index.html you posted, and presumably that is done for every resource that doesn't exist on your server (as a fallback). In the index.html you have the following script tag:

<script src="bundle.js"></script>

This is a relative path. You are actually requesting /profile/jeff/bundle.js at this point and because that doesn't exist, you end up serving the index.html as the bundle, which is problematic because it's not valid JavaScript.

You should always use /bundle.js regardless of the current URL. Similarly you'd always want /styles.css for your CSS.

<link rel="stylesheet" href="/styles.css">
<script src="/bundle.js"></script>


问:
asyncValidation on key strokes and throttled (not on blur)
The redux-form asyncValidation is great but it only works on blur. Is it possible to make it happen during key presses, and throttled? So it runs only every 300ms and on final value?

答:
Is it possible? The short answer is yes.

Is it tricky? Well, as you mentioned, theres the fact that the asyncValidation for redux-form option only works for the onBlur and you'd instead want it to work onChange.

So you could fork and add this feature into redux-form, so you can do this:

@reduxForm({
  form: 'login',
  asyncValidate: validator,
  //asyncBlurFields: ['username','password'],
  asyncChangeFields: ['username','password'], /* add this new option */
})
```

<p>For the deboucing part, you'd want to somehow debounce the <code>onChange</code> handler rather than the validate function itself, which brings up another option...</p>

<p><code>redux-form</code> exports its internal action creators which may be enough to hack it together. Particularly, there's the <code>stopAsyncValidation</code> action creator that lets you pass field-level async errors directly into a form. Pair that with the <code>onChange</code> prop for <code>Field</code>, and you actually have the right pieces to get it done like this:</p>

<p><img src="https://codesandbox.io/static/img/play-codesandbox.svg" alt="Edit Redux Form - Field-Level Validation"></p>

<pre class="lang-js prettyprint-override"><code>import React from 'react'
import { Field, reduxForm, stopAsyncValidation } from 'redux-form'
import _debounce from 'lodash.debounce'

import renderField from './renderField'

@reduxForm({form: 'debouncedOnChangeValidation'})
class DebouncedOnChangeValidationForm extends React.Component {

  customValidate = () => {
    const { form, dispatch } = this.props
    dispatch(stopAsyncValidation(form, { username: "thats wrong..." })) /* pass in async error directly! */
  }

  debounceValidate = _debounce(this.customValidate, 1000) /* decorate with debounce! */

  render() {
    const { handleSubmit, pristine, reset, submitting} = this.props
    return (
      <form onSubmit={handleSubmit}>
        <Field name="username" type="text"
          component={renderField} label="Username"
          onChange={this.debounceValidate} /* bind validation to onChange! */
        />
        <div>
          <button type="submit" disabled={submitting}>Submit</button>
          <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
        </div>
      </form>
    )
  }
}
</code>```

Additionally, to access the form values for performing validation, you'd need to use the getFormValues selector.

Of course this won't be as robust as a more built-in solution, but it may work well enough for some use cases.

Body:
Is it possible? The short answer is yes.

Is it tricky? Well, as you mentioned, theres the fact that the asyncValidation for redux-form option only works for the onBlur and you'd instead want it to work onChange.

So you could fork and add this feature into redux-form, so you can do this:

@reduxForm({
  form: 'login',
  asyncValidate: validator,
  //asyncBlurFields: ['username','password'],
  asyncChangeFields: ['username','password'], /* add this new option */
})

For the deboucing part, you'd want to somehow debounce the onChange handler rather than the validate function itself, which brings up another option...

redux-form exports its internal action creators which may be enough to hack it together. Particularly, there's the stopAsyncValidation action creator that lets you pass field-level async errors directly into a form. Pair that with the onChange prop for Field, and you actually have the right pieces to get it done like this:

import React from 'react'
import { Field, reduxForm, stopAsyncValidation } from 'redux-form'
import _debounce from 'lodash.debounce'

import renderField from './renderField'

@reduxForm({form: 'debouncedOnChangeValidation'})
class DebouncedOnChangeValidationForm extends React.Component {

  customValidate = () => {
    const { form, dispatch } = this.props
    dispatch(stopAsyncValidation(form, { username: "thats wrong..." })) /* pass in async error directly! */
  }

  debounceValidate = _debounce(this.customValidate, 1000) /* decorate with debounce! */

  render() {
    const { handleSubmit, pristine, reset, submitting} = this.props
    return (
      <form onSubmit={handleSubmit}>
        <Field name="username" type="text"
          component={renderField} label="Username"
          onChange={this.debounceValidate} /* bind validation to onChange! */
        />
        <div>
          <button type="submit" disabled={submitting}>Submit</button>
          <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
        </div>
      </form>
    )
  }
}

Additionally, to access the form values for performing validation, you'd need to use the getFormValues selector.

Of course this won't be as robust as a more built-in solution, but it may work well enough for some use cases.


问:
How to prevent Jquery append line more than one time
my code is looking for any forms and add a new token ID line.
I need to prevent adding the new line,  if I have this line.

```<code><SCRIPT LANGUAGE = "JavaScript" >
          $(document).ready(function() {
                $("form").append('<input type="hidden" name="tokenF" id="tokenID" value="#session.tokenF">');<br>
            });
    </script>
</code>```

 Please, advise me:

 Thank you .

答:
```<code>$(document).ready(function() {
    if(($('#tokenID').length) == 0) {
         $("form").append('<input type="hidden" name="tokenF" id="tokenID" value="#session.tokenF" />');

    }
});
</code>```

Body:
my code is looking for any forms and add a new token ID line.
I need to prevent adding the new line,  if I have this line.

 Please, advise me:

 Thank you .


问:
How to render Bootstrap admin template?
I have this admin panel template and I want to use it in my Django web application. I know I will have to modify the template using template tags but is that all? What all changes will I have to make. I am fairly new to Django and front end development.</p>

答:
It is pretty easy, indeed to work with Django and front-end. Answering your question: Yes, you have to change some more things to the template. You have to change links to something like

<link href="{% static 'templates/my_app/css/style.css' %}>```

Also, you have to be quite careful with the views and Models python files. The views will determine what will your administrative system will do, using the models.

Title: How to render Bootstrap admin template?

Body:
It is pretty easy, indeed to work with Django and front-end. Answering your question: Yes, you have to change some more things to the template. You have to change links to something like

<link href="{% static 'templates/my_app/css/style.css' %}>

Also, you have to be quite careful with the views and Models python files. The views will determine what will your administrative system will do, using the models.


问:
Where query after whereHas not work as it should in Laravel 5.4
In my case I have channels table that is in many to many relation with categories table.

I want to fetch the channels that their categories contain a dynamic value like doing LIKE query on title of each category. but I need to check another columns of a channel by where clause.

This is a channel structure:

```<code>[
  {
    "id": 87,
    "username": "ch1",
    "title": "ch title",
    "type": "channel",
    "members": 210424,
    "location": "tabriz",
    "created_at": "2017-05-09 01:39:44",
    "updated_at": "2017-05-16 17:19:28",
  }
]
</code>```

To get what I want I run this query:

```<code>$channels = Channel::orderBy('members', 'desc')
            ->whereHas('categories', function ($query) use ($category) {
                $query->where('title', 'LIKE', '%' . $category . '%');
            })
            ->where([
                ['visible', 1],
                ['title', 'LIKE', '%' . $trend . '%'],
                ['location', 'LIKE', '%' . $location . '%'],
                ['members', '>', $members]])
            ->get();
</code>```

Upper query return me all the channels like a query without whereHas clause whiles when I use 'whereHas' alone, it return channels with in category that I want!

Am I use wrong syntax? Is it true to use where and whereHas clauses side by side?

UPDATE:

I need do like query on channel's title or username, so I use orWhere but the result is as before! it returns all channels to me! like query without whereHas again.
So I use this query to do it,

```<code> $channels = Channel::orderBy('members', 'desc')
            ->whereHas('categories', function ($query) use ($category) {
                $query->where('title', 'LIKE', '%' . $category . '%');
            })
            ->where([
                ['visible', 1],
                ['title', 'LIKE', '%' . $trend . '%'],
                ['location', 'LIKE', '%' . $location . '%'],
                ['members', '>', $members]])
            ->orWhere([
                ['visible', 1],
                ['username', 'LIKE', '%' . $trend . '%'],
                ['location', 'LIKE', '%' . $location . '%'],
                ['members', '>', $members]])
            ->get();
</code>```

At first I thought the problem is orderBy clause as @exprator sayed, but after adding orWhere I understood that orderBy is not my issue.

答:
Try to just use ->whereHas() after the ->where(). You don't need to duplicate anything normally.

```<code>$channels = Channel::where([
            ['visible', 1],
            ['title', 'LIKE', '%' . $trend . '%'],
            ['location', 'LIKE', '%' . $location . '%'],
            ['members', '>', $members]])
        ->orWhere([
            ['visible', 1],
            ['username', 'LIKE', '%' . $trend . '%'],
            ['location', 'LIKE', '%' . $location . '%'],
            ['members', '>', $members]])
        ->whereHas('categories', function ($query) use ($category) {
            $query->where('title', 'LIKE', '%' . $category . '%');
        })
        ->orderBy('members', 'desc')
        ->get();
</code>```

Body:
In my case I have channels table that is in many to many relation with categories table.

I want to fetch the channels that their categories contain a dynamic value like doing LIKE query on title of each category. but I need to check another columns of a channel by where clause.

This is a channel structure:

[
  {
    "id": 87,
    "username": "ch1",
    "title": "ch title",
    "type": "channel",
    "members": 210424,
    "location": "tabriz",
    "created_at": "2017-05-09 01:39:44",
    "updated_at": "2017-05-16 17:19:28",
  }
]

To get what I want I run this query:

$channels = Channel::orderBy('members', 'desc')
            ->whereHas('categories', function ($query) use ($category) {
                $query->where('title', 'LIKE', '%' . $category . '%');
            })
            ->where([
                ['visible', 1],
                ['title', 'LIKE', '%' . $trend . '%'],
                ['location', 'LIKE', '%' . $location . '%'],
                ['members', '>', $members]])
            ->get();

Upper query return me all the channels like a query without whereHas clause whiles when I use 'whereHas' alone, it return channels with in category that I want!

Am I use wrong syntax? Is it true to use where and whereHas clauses side by side?

UPDATE:

I need do like query on channel's title or username, so I use orWhere but the result is as before! it returns all channels to me! like query without whereHas again.
So I use this query to do it,

 $channels = Channel::orderBy('members', 'desc')
            ->whereHas('categories', function ($query) use ($category) {
                $query->where('title', 'LIKE', '%' . $category . '%');
            })
            ->where([
                ['visible', 1],
                ['title', 'LIKE', '%' . $trend . '%'],
                ['location', 'LIKE', '%' . $location . '%'],
                ['members', '>', $members]])
            ->orWhere([
                ['visible', 1],
                ['username', 'LIKE', '%' . $trend . '%'],
                ['location', 'LIKE', '%' . $location . '%'],
                ['members', '>', $members]])
            ->get();

At first I thought the problem is orderBy clause as @exprator sayed, but after adding orWhere I understood that orderBy is not my issue.

Body:
Try to just use ->whereHas() after the ->where(). You don't need to duplicate anything normally.

$channels = Channel::where([
            ['visible', 1],
            ['title', 'LIKE', '%' . $trend . '%'],
            ['location', 'LIKE', '%' . $location . '%'],
            ['members', '>', $members]])
        ->orWhere([
            ['visible', 1],
            ['username', 'LIKE', '%' . $trend . '%'],
            ['location', 'LIKE', '%' . $location . '%'],
            ['members', '>', $members]])
        ->whereHas('categories', function ($query) use ($category) {
            $query->where('title', 'LIKE', '%' . $category . '%');
        })
        ->orderBy('members', 'desc')
        ->get();


问:
How to use proc format with the number of lines?
I have a table like this :

```<code> |Num |  Label
-----------------------
1|1   |  a thing
2|2   |  another thing
3|3   |  something else
4|4   |  whatever
</code>```

I want to replace my values of my label column by something more generic for example the first two lines : label One, the two next ones label Two ...

```<code> |Num |  Label
-----------------------
1|1   |  label One
2|2   |  label One
3|3   |  label Two
4|4   |  label Two
</code>```

How can I do that using proc format procedure ? I was wondering if I can use either the number of lines or another column like Num.

I need to do something like this :

```<code>proc format;
value label_f
low-2 = "label One"
3-high = "label Two"
;
run;
</code>```

But I want to specify the number of the line or the value of the Num column.

答:
Gatsby:

It sounds like you want to format NUM instead of LABEL.

Where you want the use the 'generic' representation defined by your format simply place a FORMAT statement in the Proc being used:

```<code>PROC PRINT data=have;
  format num label_f.;
RUN;
</code>```

If you want both num and generic, you will need to add a new column to the data for use during processing. This can be done with a view:

```<code>data have_view / view=have_view;
  set have;
  num_replicate1 = num;
  attrib num_replicate1 format=label_f. label='Generic';

  num_replacement = put (num,label_f.);
  attrib num_replacement label='Generic';   %* no format because the value is the formatted value of the original num;
run;

PROC PRINT data=have_view;
  var num num_replicate1 num_replacement;
RUN;
</code>```

If you want a the 'generic' representation of the NUM column to be used in by-processing as a grouping variable, you have several scenarios:

know apriori the generic representation is by-group clustered

use a view and process with BY or BY ... NOTSORTED if clusters are not in sort order

force ordering for use with by-group processing

use an ordered SQL view containing the replicate and process with BY

add a replicate variable to the data set, sort by the formatted value and process with BY

A direct backmap from label to num to generic is possible only if the label is known to be unique, or you know apriori the transformation backmap-num + num-map is unique.

Proc FORMAT also has a special value construct [format] that can be used to map different ranges of values according to different formatting rules.  The other range can also map to a different format that itself has an other range that maps to yet another different format.  The SAS format engine will log an error if you happen to define a recursive loop using this advanced kind of format mapping.

propaedeutics

One of my favorite Dorfman words.

Format does not replace underlying values.  Format is a map from the underlying data value to a rendered representation.  The map can be 1:1, many:1.  The MultiLabel Format (MLF) feature of the format system can even perform 1:many and many:many mappings in procedures many MLF enabled procedures (which is most of them)

To replace an underlying value with it's formatted version you need to use the PUT, PUTC or PUTN functions.  The PUT functions always outputs a character value.

character ⇒ PUT ⇒ character [ FILE / PUT ]

numeric ⇒ PUT ⇒ character [ FILE / PUT ]

There is no guarantee a mapped value will mapped to the same value, it depends on the format.

INFORMATs are similar to FORMATs, however the target value depend on the in format type

character ⇒ INPUT ⇒ character [ INFILE / INPUT ]

numeric ⇒ INPUT ⇒ character

character ⇒ INPUT ⇒ numeric [ INFILE / INPUT ]

numeric ⇒ INPUT ⇒ numeric

Custom formats are created with Proc FORMAT.  The construction of a format is specified by either the VALUE statement, or the CNTLIN= option.  CNTLIN lets you create formats directly from data and avoids really large VALUE statements that are hand-entered or code-generated (via say macro)

Data-centric 'formatting' performs the mapping through a left-join.  This is prevalent in SQL data bases.  Left-joins in SAS can be done through SQL, DATA Step MERGE BY and FORMAT application. 1:1 left-joins can also be done via Hash object SET POINT=

Body:
I have a table like this :

 |Num |  Label
-----------------------
1|1   |  a thing
2|2   |  another thing
3|3   |  something else
4|4   |  whatever

I want to replace my values of my label column by something more generic for example the first two lines : label One, the two next ones label Two ...

 |Num |  Label
-----------------------
1|1   |  label One
2|2   |  label One
3|3   |  label Two
4|4   |  label Two

How can I do that using proc format procedure ? I was wondering if I can use either the number of lines or another column like Num.

I need to do something like this :

proc format;
value label_f
low-2 = "label One"
3-high = "label Two"
;
run;

But I want to specify the number of the line or the value of the Num column.

Body:
Gatsby:

It sounds like you want to format NUM instead of LABEL.

Where you want the use the 'generic' representation defined by your format simply place a FORMAT statement in the Proc being used:

PROC PRINT data=have;
  format num label_f.;
RUN;

If you want both num and generic, you will need to add a new column to the data for use during processing. This can be done with a view:

data have_view / view=have_view;
  set have;
  num_replicate1 = num;
  attrib num_replicate1 format=label_f. label='Generic';

  num_replacement = put (num,label_f.);
  attrib num_replacement label='Generic';   %* no format because the value is the formatted value of the original num;
run;

PROC PRINT data=have_view;
  var num num_replicate1 num_replacement;
RUN;

If you want a the 'generic' representation of the NUM column to be used in by-processing as a grouping variable, you have several scenarios:

know apriori the generic representation is by-group clustered

use a view and process with BY or BY ... NOTSORTED if clusters are not in sort order

force ordering for use with by-group processing

use an ordered SQL view containing the replicate and process with BY

add a replicate variable to the data set, sort by the formatted value and process with BY

A direct backmap from label to num to generic is possible only if the label is known to be unique, or you know apriori the transformation backmap-num + num-map is unique.

Proc FORMAT also has a special value construct [format] that can be used to map different ranges of values according to different formatting rules.  The other range can also map to a different format that itself has an other range that maps to yet another different format.  The SAS format engine will log an error if you happen to define a recursive loop using this advanced kind of format mapping.

propaedeutics

One of my favorite Dorfman words.

Format does not replace underlying values.  Format is a map from the underlying data value to a rendered representation.  The map can be 1:1, many:1.  The MultiLabel Format (MLF) feature of the format system can even perform 1:many and many:many mappings in procedures many MLF enabled procedures (which is most of them)

To replace an underlying value with it's formatted version you need to use the PUT, PUTC or PUTN functions.  The PUT functions always outputs a character value.

character ⇒ PUT ⇒ character [ FILE / PUT ]

numeric ⇒ PUT ⇒ character [ FILE / PUT ]

There is no guarantee a mapped value will mapped to the same value, it depends on the format.

INFORMATs are similar to FORMATs, however the target value depend on the in format type

character ⇒ INPUT ⇒ character [ INFILE / INPUT ]

numeric ⇒ INPUT ⇒ character

character ⇒ INPUT ⇒ numeric [ INFILE / INPUT ]

numeric ⇒ INPUT ⇒ numeric

Custom formats are created with Proc FORMAT.  The construction of a format is specified by either the VALUE statement, or the CNTLIN= option.  CNTLIN lets you create formats directly from data and avoids really large VALUE statements that are hand-entered or code-generated (via say macro)

Data-centric 'formatting' performs the mapping through a left-join.  This is prevalent in SQL data bases.  Left-joins in SAS can be done through SQL, DATA Step MERGE BY and FORMAT application. 1:1 left-joins can also be done via Hash object SET POINT=


问:
Type Observable<MyData> is not assignable to MyData
```<code>export class MyClass {
    data: MyData;
    constructor(private dataService: DataService) {
      this.data = this.dataService.getData(); // error
    }
}

export class DataService{
    data: MyData;
     constructor(private http: Http) { }

    getData(): Observable<MyData>{
       return Observable.from([this.fakeData()]
          .map(res=>res as MyData));
    }

    private fakeData() : MyData {
       ...
    }
}
</code>```

I'm getting error on line

```<code> this.data = this.dataService.getData()
</code>```

Type Observable is not assignable to MyData

答:
try this, declare data as observable of MyData</p>

```<code>export class MyClass {
  data: Observable<MyData>;
 constructor(private dataService: DataService) {
   this.data = this.dataService.getData(); // error
 }
}
</code>```

Body:
export class MyClass {
    data: MyData;
    constructor(private dataService: DataService) {
      this.data = this.dataService.getData(); // error
    }
}

export class DataService{
    data: MyData;
     constructor(private http: Http) { }

    getData(): Observable<MyData>{
       return Observable.from([this.fakeData()]
          .map(res=>res as MyData));
    }

    private fakeData() : MyData {
       ...
    }
}

I'm getting error on line

 this.data = this.dataService.getData()

Type Observable is not assignable to MyData

Body:
try this, declare data as observable of MyData

export class MyClass {
  data: Observable<MyData>;
 constructor(private dataService: DataService) {
   this.data = this.dataService.getData(); // error
 }
}


问:
Access variables/functions of instantiating class
I am trying to write code which matches what is happening physically. I writing code which accesses a physical chassis which has two hardware devices in it. Right now I have a chassis class which I want to have chassis level variables and functions (Hostname, port, readVariable, ...). I also have device level classes which have device specific functions but need access to information from the chassis level class.

Right now that looks something like this pseudo code:

```<code>class Chassis {
  public:
    Chassis():

    String hostname;
    int port;
    Dev1 device1;
    Dev2 device2;

    int readVar(String varName, String *result);
    int writeVar(String varName, String varVal);
}

class Dev1 {
  public:
    Dev1();
    int updateStatusVars();
}

Dev1::Dev1() {
}

int Dev1::updateStatusVars() {
  int status = Chassis::readVar("Var1",var1Val);
  return status;
}
</code>```

Is there a better way to approach this? I want the main class to only have one instance of the chassis which in turn holds the references to the devices. Inheritance doesn't really solve this since I would have to have two devices each of which inherit from chassis. Each of those devices could have different hostnames and ports. I don't want that. It's the situation I'm specifically trying to avoid. I want have a single reference to hostname and port accessible by each device and certain functions which the devices can access also.

What is the best way to do this?

答:
Chassis doesn't know about the specific hardware installed in it, instead it defines interfaces for I/O.  The devices also exist as separate entities that may or may not be plugged into the Chassis.  I would model it like so (pseudocode)...</p>

```<code>class PCIInterface
{
public:
    PCIInterface(){}
    virtual ~PCIInterface(){}
    virtual void Update()=0;
    virtual int ReadVar ( String varName, String *result )=0;
    virtual int WriteVar( String varName, String value )=0;
};

class Device : public PCIInterface
{
public:
    Device(){}
    virtual ~Device(){}

    void Powerup( PCIInterface *chassis );

    /* PCIInterface */
    virtual void Update();
    virtual int ReadVar( String varName, String *result );
    virtual int WriteVar( String varName, String value );

protected:
    PCIInterface *m_chassis;
}

void Device::Powerup( PCIInterface *chassis )
{
m_chassis = chassis;
}

class Chassis : public PCIInterface
{
public:
    Chassis(){ m_slots.resize( MAX_SLOTS ); }
    virtual ~Chassis(){}

    void PlugIn( const int slot_id, Device *device );

    /* PCIInterface */
    virtual void Update();
    virtual int ReadVar( String varName, String *result );
    virtual int WriteVar( String varName, String value );

protected:
    std::vector<PCIInterface*> m_slots;
}

void Chassis::PlugIn( const int slot_id, Device *device )
{
assert( slot_id < m_slots.size() );
m_slots[ slot_id ] = device;
device->PowerUp( this );
}

void Chassis::Update()
{
for( auto device : m_slots )
    {
    if( *device ) device->Update();
    }
}

class DeviceFlower : public Device
{
...
}

void DeviceFlower::Update()
{
String str;
m_chassis->ReadVar( "ChassisName", &str );
cout << str;
}

class DeviceRock : public Device
{
...
}

void main()
{
auto the_chassis = Chassis();
auto first_device = DeviceFlower();
auto second_device = DeviceRock();

the_chassis.PlugIn( 0, &first_device );
the_chassis.PlugIn( 1, &second_device );

while( true )
    {
    the_chassis.Update();
    }

}
</code>```

Body:
I am trying to write code which matches what is happening physically. I writing code which accesses a physical chassis which has two hardware devices in it. Right now I have a chassis class which I want to have chassis level variables and functions (Hostname, port, readVariable, ...). I also have device level classes which have device specific functions but need access to information from the chassis level class.

Right now that looks something like this pseudo code:

class Chassis {
  public:
    Chassis():

    String hostname;
    int port;
    Dev1 device1;
    Dev2 device2;

    int readVar(String varName, String *result);
    int writeVar(String varName, String varVal);
}

class Dev1 {
  public:
    Dev1();
    int updateStatusVars();
}

Dev1::Dev1() {
}

int Dev1::updateStatusVars() {
  int status = Chassis::readVar("Var1",var1Val);
  return status;
}

Is there a better way to approach this? I want the main class to only have one instance of the chassis which in turn holds the references to the devices. Inheritance doesn't really solve this since I would have to have two devices each of which inherit from chassis. Each of those devices could have different hostnames and ports. I don't want that. It's the situation I'm specifically trying to avoid. I want have a single reference to hostname and port accessible by each device and certain functions which the devices can access also.

What is the best way to do this?

Body:
Chassis doesn't know about the specific hardware installed in it, instead it defines interfaces for I/O.  The devices also exist as separate entities that may or may not be plugged into the Chassis.  I would model it like so (pseudocode)...

class PCIInterface
{
public:
    PCIInterface(){}
    virtual ~PCIInterface(){}
    virtual void Update()=0;
    virtual int ReadVar ( String varName, String *result )=0;
    virtual int WriteVar( String varName, String value )=0;
};

class Device : public PCIInterface
{
public:
    Device(){}
    virtual ~Device(){}

    void Powerup( PCIInterface *chassis );

    /* PCIInterface */
    virtual void Update();
    virtual int ReadVar( String varName, String *result );
    virtual int WriteVar( String varName, String value );

protected:
    PCIInterface *m_chassis;
}

void Device::Powerup( PCIInterface *chassis )
{
m_chassis = chassis;
}

class Chassis : public PCIInterface
{
public:
    Chassis(){ m_slots.resize( MAX_SLOTS ); }
    virtual ~Chassis(){}

    void PlugIn( const int slot_id, Device *device );

    /* PCIInterface */
    virtual void Update();
    virtual int ReadVar( String varName, String *result );
    virtual int WriteVar( String varName, String value );

protected:
    std::vector<PCIInterface*> m_slots;
}

void Chassis::PlugIn( const int slot_id, Device *device )
{
assert( slot_id < m_slots.size() );
m_slots[ slot_id ] = device;
device->PowerUp( this );
}

void Chassis::Update()
{
for( auto device : m_slots )
    {
    if( *device ) device->Update();
    }
}

class DeviceFlower : public Device
{
...
}

void DeviceFlower::Update()
{
String str;
m_chassis->ReadVar( "ChassisName", &str );
cout << str;
}

class DeviceRock : public Device
{
...
}

void main()
{
auto the_chassis = Chassis();
auto first_device = DeviceFlower();
auto second_device = DeviceRock();

the_chassis.PlugIn( 0, &first_device );
the_chassis.PlugIn( 1, &second_device );

while( true )
    {
    the_chassis.Update();
    }

}


问:
How to parse a String in Java without using .parse()?
I'm trying to write a program that will take a string and parse it into two outputs, with the delimiter being a comma. It loops until the user enters the character "q".

i.e.: Console prompts to enter an input, and user inputs "first, second" and then "q" for the second prompt, and the output will be:

```<code>Enter input string:
First word: first
Second word: second

Enter input string:
</code>```

If there is no comma in the input, it throws an error and prompts again

i.e. User inputs "first second" and the output will be:

```<code>Enter input string:
Error: No comma in string
Enter input string:
</code>```

Below is what I have so far:

```<code>import java.util.Scanner;

public class ParseStrings {
   public static void main(String[] args) {
         Scanner scnr = new Scanner(System.in); // Scanner for standard input
         Scanner inSS = null;                   // Scanner to write input to buffer
         String firstWord = "";                 // First word string
         String secondWord = "";                // Second word string
         String userInput = "";                 // Input from prompt
         int i = 0;                             // Loop iterator
         boolean inputDone = false;             // Boolean to repeat while loop
         boolean hasComma = false;              // Boolean to check for comma

         // Do while inputDone is false
         while (!inputDone) {

            //Prompt user to input a string
            System.out.println("Enter input string: ");

            // Write string to userInput
            userInput = scnr.nextLine();

            // Exit program if user inputs q
            if((userInput.equals("q"))) {
               inputDone = true;
               break;
            }
            else{

               // Write userInput to buffer
               inSS = new Scanner(userInput);

               // Write first word from buffer
               firstWord = inSS.next();

               // Loop through first word string
               for (i = 0; i < firstWord.length(); ++i) {

                  // If char is a comma, write everything after to secondWord and set inputDone to true
                  if(firstWord.charAt(i) == ',') {
                     secondWord = inSS.next();
                     hasComma = true;
                  }
               }

               // If hasComma is false, return error
               if (!hasComma){
                  System.out.println("Error: No comma in string");
               }
               // Else print first word and second word
               else {
                  System.out.println("First word: " + firstWord);
                  System.out.println("Second word: " + secondWord);
                  System.out.println("");
                  System.out.println("");
               }
            }
         }
        return;
       }
    }
</code>```

Problems:

I don't know how to remove the comma from the output

If there is no space it errors out

If there is a space between the first word and the comma, it writes firstWord but does not overwrite the previous value for secondWord (or errors if it's the first input given)

I'm taking a beginner's Java course and we have not gone over the .parse() method yet, so it's not really an option at this time.

Thank you in advance!

答:
Try using string split.

```<code>String str="first, second";
String[] arr=str.split(",");
if(arr.length == 2) {
    System.out.println("First :" + arr[0]);
    System.out.println("Second :" + arr[1]);
} if(arr.length > 2) {
    System.out.println("More than 1 comma used.");
} else {
    System.out.println("Error. No comma found.");
}
</code>```

You can use trim() in case your string has any spaces around comma.

Body:
I'm trying to write a program that will take a string and parse it into two outputs, with the delimiter being a comma. It loops until the user enters the character "q".

i.e.: Console prompts to enter an input, and user inputs "first, second" and then "q" for the second prompt, and the output will be:

Enter input string:
First word: first
Second word: second

Enter input string:

If there is no comma in the input, it throws an error and prompts again

i.e. User inputs "first second" and the output will be:

Enter input string:
Error: No comma in string
Enter input string:

Below is what I have so far:

import java.util.Scanner;

public class ParseStrings {
   public static void main(String[] args) {
         Scanner scnr = new Scanner(System.in); // Scanner for standard input
         Scanner inSS = null;                   // Scanner to write input to buffer
         String firstWord = "";                 // First word string
         String secondWord = "";                // Second word string
         String userInput = "";                 // Input from prompt
         int i = 0;                             // Loop iterator
         boolean inputDone = false;             // Boolean to repeat while loop
         boolean hasComma = false;              // Boolean to check for comma

         // Do while inputDone is false
         while (!inputDone) {

            //Prompt user to input a string
            System.out.println("Enter input string: ");

            // Write string to userInput
            userInput = scnr.nextLine();

            // Exit program if user inputs q
            if((userInput.equals("q"))) {
               inputDone = true;
               break;
            }
            else{

               // Write userInput to buffer
               inSS = new Scanner(userInput);

               // Write first word from buffer
               firstWord = inSS.next();

               // Loop through first word string
               for (i = 0; i < firstWord.length(); ++i) {

                  // If char is a comma, write everything after to secondWord and set inputDone to true
                  if(firstWord.charAt(i) == ',') {
                     secondWord = inSS.next();
                     hasComma = true;
                  }
               }

               // If hasComma is false, return error
               if (!hasComma){
                  System.out.println("Error: No comma in string");
               }
               // Else print first word and second word
               else {
                  System.out.println("First word: " + firstWord);
                  System.out.println("Second word: " + secondWord);
                  System.out.println("");
                  System.out.println("");
               }
            }
         }
        return;
       }
    }

Problems:

I don't know how to remove the comma from the output

If there is no space it errors out

If there is a space between the first word and the comma, it writes firstWord but does not overwrite the previous value for secondWord (or errors if it's the first input given)

I'm taking a beginner's Java course and we have not gone over the .parse() method yet, so it's not really an option at this time.

Thank you in advance!

Body:
Try using string split.

String str="first, second";
String[] arr=str.split(",");
if(arr.length == 2) {
    System.out.println("First :" + arr[0]);
    System.out.println("Second :" + arr[1]);
} if(arr.length > 2) {
    System.out.println("More than 1 comma used.");
} else {
    System.out.println("Error. No comma found.");
}

You can use trim() in case your string has any spaces around comma.


问:
Android: Convert Stream to String without running out of memory
I have an android client that communicates with the server via REST-ful endpoints and JSON. Because of this, I have the need to retrieve the full server response prior to converting it into a Hash. I have this code in place to do that (found on the internet someplace):

```<code>private static String convertStreamToString(InputStream is) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}
</code>```

The code works for the most part, however I am seeing reports of crashes in the field from clients with an OutOfMemory exception on the line:

```<code>    while ((line = reader.readLine()) != null) {
</code>```

The full stack trace is:

```<code>java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:200)
    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
    at java.lang.Thread.run(Thread.java:1102)
Caused by: java.lang.OutOfMemoryError
    at java.lang.String.(String.java:468)
    at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
    at java.lang.StringBuilder.toString(StringBuilder.java:664)
    at java.io.BufferedReader.readLine(BufferedReader.java:448)
    at com.appspot.myapp.util.RestClient.convertStreamToString(RestClient.java:303)
    at com.appspot.myapp.util.RestClient.executeRequest(RestClient.java:281)
    at com.appspot.myapp.util.RestClient.Execute(RestClient.java:178)
    at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1178)
    at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:185)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    ... 4 more
</code>```

My question: is there any way to solve this problem aside from sending smaller chunks of data from the server?

Thanks!

答:
Android has restrictions on the maximum amount of memory you can allocate to your application. You could consider reading the stream on the fly and not save the whole thing into a String if the response is very large. But you should consider following best practice.

You should store the data in a sqlite database or to a regular file. It's not best practice to do what you're doing as the user might hit the home button or receive a phone call when you're in the middle of saving the response. It is better to use a database so that you can come back to the state where you were interrupted. Then you also do not have to worry about running out of memory.

Have you watched this talk on best practices for communicating with REST services from Android? http://www.youtube.com/watch?v=xHXn3Kg2IQE?8m50s (8:50 and 11:20). Highly recommended to clear out best practices and why one should not retrieve REST data without using a database.

In short, consider saving to an sqlite database or a file. If the data is very large you could perhaps consider compressing it before you store it.

Body:
I have an android client that communicates with the server via REST-ful endpoints and JSON. Because of this, I have the need to retrieve the full server response prior to converting it into a Hash. I have this code in place to do that (found on the internet someplace):

private static String convertStreamToString(InputStream is) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}

The code works for the most part, however I am seeing reports of crashes in the field from clients with an OutOfMemory exception on the line:

    while ((line = reader.readLine()) != null) {

The full stack trace is:

java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:200)
    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
    at java.lang.Thread.run(Thread.java:1102)
Caused by: java.lang.OutOfMemoryError
    at java.lang.String.(String.java:468)
    at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
    at java.lang.StringBuilder.toString(StringBuilder.java:664)
    at java.io.BufferedReader.readLine(BufferedReader.java:448)
    at com.appspot.myapp.util.RestClient.convertStreamToString(RestClient.java:303)
    at com.appspot.myapp.util.RestClient.executeRequest(RestClient.java:281)
    at com.appspot.myapp.util.RestClient.Execute(RestClient.java:178)
    at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1178)
    at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:185)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    ... 4 more

My question: is there any way to solve this problem aside from sending smaller chunks of data from the server?

Thanks!