问:
Ionic serve command resets the index.html page
I've recently started developing in Ionic, and I find that once I've made changes to the index.html file and run it (ionic serve), it resets the index.html file.

I think I might be missing a step somewhere, any ideas?

Found the error. I was editing the file in the www folder and not the one in the src folder. Once I updated the index.html file in the src folder, the changes appear in the file in the www folder.

However, I find that when I update the controllers in the src/js folder, they are not updated in the www/js folder, so I have to make updates to the files in the www/js folder.

Not really sure of what's going on.

答:
src folder is true development folder.

When ionic builds the app for you it automatically copies all the required files from src/ to www/.

If its not happening there might be something wrong with project, try removing and adding platform again.


来源: stackexchange

问:
Can't retrive the good information from JSON on C#
I'm trying to get information from the Google API (YT). I need to take the videoId from the API of Google.

So I download the JSON page and trying to deserialize my result but he doesn't works.

This is the JSON result

```<code>    {
   "kind": "youtube#playlistItemListResponse",
   "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/E6IhaTG5XEbqo_uSYhCcIvQhtwY\"",
   "nextPageToken": "CDIQAA",
   "pageInfo": {
   "totalResults": 180,
   "resultsPerPage": 50
   },
  "items": [
  {
   "kind": "youtube#playlistItem",
   "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/0cAZGJiF62yaNO7GwJlJBsc7DqY\"",
   "id": "UExNQzlLTmtJbmNLdFB6Z1ktNXJtaHZqN2ZheDhmZHhvai41RDlFNzlCQjE5NzcyQTYx",
   "snippet": {
    "publishedAt": "2016-05-19T13:47:40.000Z",
    "channelId": "UCs72iRpTEuwV3y6pdWYLgiw",
    "title": "Katy Perry - Dark Horse (Official) ft. Juicy J",
    "description": "Bla bla bla",
    },
    "channelTitle": "#RedMusic: Just Hits",
    "playlistId": "PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj",
    "position": 0,
    "resourceId": {
     "kind": "youtube#video",
     "videoId": "0KSOMA3QBU0"
    }
   }
  },
</code>```

And this is my code for taking the videoId

```<code>JObject jObj = (JObject)JsonConvert.DeserializeObject(x.Result);
foreach (var item in jObj["items"])
{
  string title = item["videoId"].ToString();
}
</code>```

And when I'm start my app I have an error with System.NullReferenceException.

Where is my problem ?

Thanks

答:
Ok i've found the solution, i've added in var g the next item

```<code>var g = item["snippet"]["resourceId"];
</code>```

If I don't put the good "path" it doesn't works.
So now it's working and I have the video link.

Thanks all for your help !

ContentLicense: CC BY-SA 3.0

Body:
I'm trying to get information from the Google API (YT). I need to take the videoId from the API of Google.

So I download the JSON page and trying to deserialize my result but he doesn't works.

This is the JSON result

    {
   "kind": "youtube#playlistItemListResponse",
   "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/E6IhaTG5XEbqo_uSYhCcIvQhtwY\"",
   "nextPageToken": "CDIQAA",
   "pageInfo": {
   "totalResults": 180,
   "resultsPerPage": 50
   },
  "items": [
  {
   "kind": "youtube#playlistItem",
   "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/0cAZGJiF62yaNO7GwJlJBsc7DqY\"",
   "id": "UExNQzlLTmtJbmNLdFB6Z1ktNXJtaHZqN2ZheDhmZHhvai41RDlFNzlCQjE5NzcyQTYx",
   "snippet": {
    "publishedAt": "2016-05-19T13:47:40.000Z",
    "channelId": "UCs72iRpTEuwV3y6pdWYLgiw",
    "title": "Katy Perry - Dark Horse (Official) ft. Juicy J",
    "description": "Bla bla bla",
    },
    "channelTitle": "#RedMusic: Just Hits",
    "playlistId": "PLMC9KNkIncKtPzgY-5rmhvj7fax8fdxoj",
    "position": 0,
    "resourceId": {
     "kind": "youtube#video",
     "videoId": "0KSOMA3QBU0"
    }
   }
  },

And this is my code for taking the videoId

JObject jObj = (JObject)JsonConvert.DeserializeObject(x.Result);
foreach (var item in jObj["items"])
{
  string title = item["videoId"].ToString();
}

And when I'm start my app I have an error with System.NullReferenceException.

Where is my problem ?

Thanks

Body:
Ok i've found the solution, i've added in var g the next item

var g = item["snippet"]["resourceId"];

If I don't put the good "path" it doesn't works.
So now it's working and I have the video link.

Thanks all for your help !


问:
Pressing back button shows same activity
I have two Activities.

LoginActivity

HomeScreen

I also have a splash screen with this setting:

```<code><activity android:name=".SplashScreen"
            android:theme="@style/AppTheme.NoActionBar"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>
</code>```

The Splash Screen then transfers the user to the HomeScreen by using this code:

```<code>Intent intent = new Intent(SplashScreen.this, HomeScreen.class);
</code>```

Inside the HomeScreen Activity, I check if the user is already signed in or not. If he's not signed in, I transfer him to the LoginActivity:

```<code> mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(FirebaseAuth firebaseAuth) {
                if(firebaseAuth.getCurrentUser() == null)
                {
                    Intent intent = new Intent(HomeScreen.this,LoginActivity.class);
                    Toast.makeText(HomeScreen.this,"H>L on no login",Toast.LENGTH_LONG).show(); //toast to show me why my app is in infinite loop
                    startActivity(intent);
                }
            }
        };
</code>```

On the LoginActivity, I have a simple Login button which uses FireBase Google Authentication. Also, I check if the user is already signed in or not, and if he is, he's transferred to HomeScreen Activity:

```<code>mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                if(firebaseAuth.getCurrentUser() != null)
                {
                    Intent intent = new Intent(LoginActivity.this,HomeScreen.class);
                    Toast.makeText(LoginActivity.this,"L>H already signed in",Toast.LENGTH_LONG).show();
                    startActivity(intent);
                }
            }
        };
</code>```

And, also:

```<code>private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
        Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            Intent intent = new Intent(LoginActivity.this,HomeScreen.class);
                            Toast.makeText(LoginActivity.this,"L>H on login",Toast.LENGTH_LONG).show();
                            startActivity(intent);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(LoginActivity.this, "Authentication failed.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
</code>```

Now, the problem is: When I open the app, I get a splash screen and I'm transferred to the Login page. Then when I press back, I get the Login page AGAIN instead of exiting the app. Also, once I'm singed in: I get the splash screen and I'm taken to the HomeScreen. Then if I press back, I am taken to the HomeScreen AGAIN instead of exiting the app.

Please help me out. I searched StackOverflow, but didn't quite reach anywhere. Any help is appreciated. Ask me for updates if you need more info! :)

答:
Simply do like this.    </p>

```<code>       img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
</code>```

Body:
I have two Activities.

LoginActivity

HomeScreen

I also have a splash screen with this setting:

<activity android:name=".SplashScreen"
            android:theme="@style/AppTheme.NoActionBar"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

The Splash Screen then transfers the user to the HomeScreen by using this code:

Intent intent = new Intent(SplashScreen.this, HomeScreen.class);

Inside the HomeScreen Activity, I check if the user is already signed in or not. If he's not signed in, I transfer him to the LoginActivity:

 mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(FirebaseAuth firebaseAuth) {
                if(firebaseAuth.getCurrentUser() == null)
                {
                    Intent intent = new Intent(HomeScreen.this,LoginActivity.class);
                    Toast.makeText(HomeScreen.this,"H>L on no login",Toast.LENGTH_LONG).show(); //toast to show me why my app is in infinite loop
                    startActivity(intent);
                }
            }
        };

On the LoginActivity, I have a simple Login button which uses FireBase Google Authentication. Also, I check if the user is already signed in or not, and if he is, he's transferred to HomeScreen Activity:

mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                if(firebaseAuth.getCurrentUser() != null)
                {
                    Intent intent = new Intent(LoginActivity.this,HomeScreen.class);
                    Toast.makeText(LoginActivity.this,"L>H already signed in",Toast.LENGTH_LONG).show();
                    startActivity(intent);
                }
            }
        };

And, also:

private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
        Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            Intent intent = new Intent(LoginActivity.this,HomeScreen.class);
                            Toast.makeText(LoginActivity.this,"L>H on login",Toast.LENGTH_LONG).show();
                            startActivity(intent);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(LoginActivity.this, "Authentication failed.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

Now, the problem is: When I open the app, I get a splash screen and I'm transferred to the Login page. Then when I press back, I get the Login page AGAIN instead of exiting the app. Also, once I'm singed in: I get the splash screen and I'm taken to the HomeScreen. Then if I press back, I am taken to the HomeScreen AGAIN instead of exiting the app.

Please help me out. I searched StackOverflow, but didn't quite reach anywhere. Any help is appreciated. Ask me for updates if you need more info! :)

Body:
Simply do like this.

       img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });


问:
Center aligning Dropdown component in Bootstrap 4 not working properly
I have reviewed this answer which will help me to accomplish my ultimate goal (by tweaking CSS) but my question is regarding component and styling that bootstrap has provided us.

Problem: The dropdown button is aligned just as required but the dropdown menu is misaligned. Try resizing the window to verify small devices, tablet sizes.

Changing number of columns by modifying col-sm-12 also helps a bit but the misalignment still persists on small devices.

Here's the Minimal, Complete and Verifiable: JsFiddle Example

```<code><div class="container-fluid">
        <div class="row justify-content-center text-center">
            <div class="col-sm-12 align-self-center">
                <div class="dropdown">
                    <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                        Select Category
                    </button>
                    <div class="dropdown-menu"
                         aria-labelledby="dropdownMenuButton">

                            <a class="dropdown-item" href="#">Category1</a>
                            <a class="dropdown-item" href="#">Category2</a>
                            <a class="dropdown-item" href="#">Category3</a>
                    </div>
                </div>
            </div>

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

The two classes which allow us to center align -

justify-content-center :
https://v4-alpha.getbootstrap.com/layout/grid/#horizontal-alignment

text-center : https://v4-alpha.getbootstrap.com/utilities/typography/#text-alignment

Question:

Why don't the above classes apply to the dropdown menu but only to the dropdown button?

Are there are any helpful Bootstrap 4 styling classes that I'm missing that would fix that misalignment?

答:
It's because your dropdown menu is positioned absolutely - you need to overwrite it's styles and position it in the center rather than on the left:

```<code>.justify-content-center .dropdown-menu {
   left: 50%;
   transform: translateX(-50%);
}
</code>```

Updated fiddle

Body:
I have reviewed this answer which will help me to accomplish my ultimate goal (by tweaking CSS) but my question is regarding component and styling that bootstrap has provided us.

Problem: The dropdown button is aligned just as required but the dropdown menu is misaligned. Try resizing the window to verify small devices, tablet sizes.

Changing number of columns by modifying col-sm-12 also helps a bit but the misalignment still persists on small devices.

Here's the Minimal, Complete and Verifiable: JsFiddle Example

                    <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                        Select Category
                    </button>

                            Category1
                            Category2
                            Category3

The two classes which allow us to center align -

justify-content-center :
https://v4-alpha.getbootstrap.com/layout/grid/#horizontal-alignment

text-center : https://v4-alpha.getbootstrap.com/utilities/typography/#text-alignment

Question:

Why don't the above classes apply to the dropdown menu but only to the dropdown button?

Are there are any helpful Bootstrap 4 styling classes that I'm missing that would fix that misalignment?

Body:
It's because your dropdown menu is positioned absolutely - you need to overwrite it's styles and position it in the center rather than on the left:

.justify-content-center .dropdown-menu {
   left: 50%;
   transform: translateX(-50%);
}

Updated fiddle


问:
C# Mediaplayer doesn't play mp3 file from resources
Mediaplayer didn't work for me, so I moved to a simple test project (C# Console App). I added my .mp3 file to the project like this:

Right click project name (test) in solution explorer

add folder resources

Right click the resources folder in solution explorer

Add my warn.mp3 file

left click the warn.mp3 file

Changed Build Action to Resource in the properties window.

Sadly, this code doesnt work:

```<code>namespace test
{
    class Program
    {
        public static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            player.Open(new Uri("resources/warn.mp3", UriKind.Relative));
            player.Play();
            Console.ReadKey();
        }
    }
}
</code>```

However, this one does:

```<code>namespace test
{
    class Program
    {
        public static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            player.Open(new Uri("C:\\Users\\Krepsy3\\Documents\\Programs\\OOP\\test\\test\\resources\\warn.mp3", UriKind.Absolute));
            player.Play();
            Console.ReadKey();
        }
    }
}
</code>```

Any idea about what is wrong?

答:
What about this:</p>

```<code>namespace test
{
    class Program
    {
        public static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            player.Open(new Uri(System.Environment.CurrentDirectory + "\resources\warn.mp3", UriKind.Relative));
            player.Play();
            Console.ReadKey();
        }
    }
}
</code>```

Body:
Mediaplayer didn't work for me, so I moved to a simple test project (C# Console App). I added my .mp3 file to the project like this:

Right click project name (test) in solution explorer

add folder resources

Right click the resources folder in solution explorer

Add my warn.mp3 file

left click the warn.mp3 file

Changed Build Action to Resource in the properties window.

Sadly, this code doesnt work:

namespace test
{
    class Program
    {
        public static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            player.Open(new Uri("resources/warn.mp3", UriKind.Relative));
            player.Play();
            Console.ReadKey();
        }
    }
}

However, this one does:

namespace test
{
    class Program
    {
        public static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            player.Open(new Uri("C:\\Users\\Krepsy3\\Documents\\Programs\\OOP\\test\\test\\resources\\warn.mp3", UriKind.Absolute));
            player.Play();
            Console.ReadKey();
        }
    }
}

Any idea about what is wrong?

Body:
What about this:

namespace test
{
    class Program
    {
        public static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            player.Open(new Uri(System.Environment.CurrentDirectory + "\resources\warn.mp3", UriKind.Relative));
            player.Play();
            Console.ReadKey();
        }
    }
}


问:
Android message object PendingIntent, getting null Intent.getExtras().getString("mystring")
I am calling fragment inside the activity on clicking on bottom bar.
the fragment has following message object in fragment.

```<code>@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {

      Intent moreSelectionIntent = new Intent(getActivity(), MainActivity.class);
      moreSelectionIntent.putExtra("selection",Integer.toString(position));
     PendingIntent pendingIntent = PendingIntent.getActivity(getActivity().getApplicationContext(), 0, moreSelectionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
     }        `
</code>```

the fragment calls activity and passes PendingIntent. when I get string from the intent using below code I am getting NULL in activity
below is the piece of code in activity

```<code> Intent i = this.getIntent();
    Log.i(TAG, "intenet------->"+i);

    String moreSelection = i.getExtras().getString("selection");
    Log.i(TAG, "moreSelection Bundle------->"+moreSelection);

    if(moreSelection!=null)
    { System.out.println("message"+moreSelection);}
</code>```

答: You must add your extra string to be able to get it. Add it to your pendingIntent first.</p>

Body:
I am calling fragment inside the activity on clicking on bottom bar.
the fragment has following message object in fragment.

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {

      Intent moreSelectionIntent = new Intent(getActivity(), MainActivity.class);
      moreSelectionIntent.putExtra("selection",Integer.toString(position));
     PendingIntent pendingIntent = PendingIntent.getActivity(getActivity().getApplicationContext(), 0, moreSelectionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
     }        `

the fragment calls activity and passes PendingIntent. when I get string from the intent using below code I am getting NULL in activity
below is the piece of code in activity

 Intent i = this.getIntent();
    Log.i(TAG, "intenet------->"+i);

    String moreSelection = i.getExtras().getString("selection");
    Log.i(TAG, "moreSelection Bundle------->"+moreSelection);

    if(moreSelection!=null)
    { System.out.println("message"+moreSelection);}


问:
Howto display localized characters
I have a MySQL database, php code to retrieve from the database, and an Android program that recieve the output from the php code via http post.

My localized characters displays as question marks in my program.  I have tried different charsets in my database.  utf8_general_ci, utf8_unicode_ci, latin1_general_ci - still questions marks.  In html I could use the code ø, but not in an Android program - and I shouldn't have to.

First of all, where is this problem comming from?  The database itself have no problems displaying localized characters with utf8_.  Android also have no problems.  Is it the http post request or php that have problems with this?

答:
I would check layer by layer:

Even the DB encoding is UTF8 - you are sure the value is properly stored?

Do you have a way to test case the API (i.e. by using a web interface), if needed you would do packet inspection and check the proper UTF-8 value

Is your PHP API sending the correct encoding?

When reading the HTTP response in Android (i.e. parsing the Stream), are you supplying a encoding & is it the correct one?

ContentLicense: CC BY-SA 2.5

Title: Howto display localized characters


问:
Check if the hostname is fully qualified (FQDN)
```<code>#!/bin/bash

for h in "bert" "ernie" "www.google.com"
do
    host $h 2>&1 > /dev/null
    if [ $? -eq 0 ]
    then
        echo "$h is a FQDN"
    else
        echo "$h is not a FQDN"
    fi
done
</code>```

Like to insert the output of 'hostname -f' instead of 'bert' or www.google.com
If the hostname is FQDN the script should continue, if not an error message should occur. PS. It is NOT important if the TLD exist or not. eg. hostname.domain is a FQDN or hostname.domain.tld is a FQDN. If the TLD is valid on the internet is not important to me. output of hostname -f

答:
The usual way to ensure a hostname is fully-qualified is to specify the final . (that is usually omitted): example.com..

However, from comments to the question, it appears that you want a simple string comparison - if a . appears anywhere, assume the name is valid, otherwise error.  The simplest way is to compare the name against a copy with first . removed - if the two are identical, then there was no . to remove:

```<code>if [ "$h" != "${h/.}" ]
then echo "$h is acceptable" >&2
else echo "$h is not acceptable" >&2
fi
</code>```

Body:
#!/bin/bash

for h in "bert" "ernie" "www.google.com"
do
    host $h 2>&1 > /dev/null
    if [ $? -eq 0 ]
    then
        echo "$h is a FQDN"
    else
        echo "$h is not a FQDN"
    fi
done

Like to insert the output of 'hostname -f' instead of 'bert' or www.google.com
If the hostname is FQDN the script should continue, if not an error message should occur. PS. It is NOT important if the TLD exist or not. eg. hostname.domain is a FQDN or hostname.domain.tld is a FQDN. If the TLD is valid on the internet is not important to me. output of hostname -f

Body:
The usual way to ensure a hostname is fully-qualified is to specify the final . (that is usually omitted): example.com..

However, from comments to the question, it appears that you want a simple string comparison - if a . appears anywhere, assume the name is valid, otherwise error.  The simplest way is to compare the name against a copy with first . removed - if the two are identical, then there was no . to remove:

if [ "$h" != "${h/.}" ]
then echo "$h is acceptable" >&2
else echo "$h is not acceptable" >&2
fi


问:
How to check the value belongs to an interval in JSON
I have an input field

```<code><md-input-container ng-if="gpa.grade_type==2">
    <input type="text" ng-model="gpa.grade_percent" aria-label="Grade">
</md-input-container>
</code>```

I want to check the gpa.grade_percent "percent_grade_from": 93 - "percent_grade_to": 96, value in JSON in which interval it fits
so that I have to show the interval related scale in the next field.

```<code><td>
    <span ng-bind="gpa.grade_scale"></span>
</td>
</code>```

JSON :

```<code>[
  {
    "id": 2,
    "letter_grade": "A",
    "percent_grade_from": 93,
    "percent_grade_to": 96,
    "scale": "4.0",
    "honors_gpa_from": "4.3",
    "honors_gpa_to": "4.4",
    "ap_ib_gpa_from": "4.8",
    "ap_ib_gpa_to": "4.9"
  },
  {
    "id": 3,
    "letter_grade": "A-",
    "percent_grade_from": 90,
    "percent_grade_to": 92,
    "scale": "3.7",
    "honors_gpa_from": "3.9",
    "honors_gpa_to": "4.2",
    "ap_ib_gpa_from": "4.4",
    "ap_ib_gpa_to": "4.7"
  },
  {
    "id": 4,
    "letter_grade": "B+",
    "percent_grade_from": 87,
    "percent_grade_to": 89,
    "scale": "3.3",
    "honors_gpa_from": "3.6",
    "honors_gpa_to": "3.8",
    "ap_ib_gpa_from": "4.1",
    "ap_ib_gpa_to": "4.3"
  },
  {
    "id": 5,
    "letter_grade": "B",
    "percent_grade_from": 83,
    "percent_grade_to": 86,
    "scale": "3.0",
    "honors_gpa_from": "3.3",
    "honors_gpa_to": "3.5",
    "ap_ib_gpa_from": "3.8",
    "ap_ib_gpa_to": "4.0"
  },
  {
    "id": 6,
    "letter_grade": "B-",
    "percent_grade_from": 80,
    "percent_grade_to": 82,
    "scale": "2.7",
    "honors_gpa_from": "2.0",
    "honors_gpa_to": "3.2",
    "ap_ib_gpa_from": "3.4",
    "ap_ib_gpa_to": "3.7"
  },
  {
    "id": 7,
    "letter_grade": "C+",
    "percent_grade_from": 77,
    "percent_grade_to": 79,
    "scale": "2.3",
    "honors_gpa_from": "2.6",
    "honors_gpa_to": "2.8",
    "ap_ib_gpa_from": "3.1",
    "ap_ib_gpa_to": "3.3"
  },
  {
    "id": 8,
    "letter_grade": "C",
    "percent_grade_from": 73,
    "percent_grade_to": 76,
    "scale": "2.0",
    "honors_gpa_from": "2.3",
    "honors_gpa_to": "2.5",
    "ap_ib_gpa_from": "2.8",
    "ap_ib_gpa_to": "3.0"
  },
  {
    "id": 9,
    "letter_grade": "C-",
    "percent_grade_from": 70,
    "percent_grade_to": 72,
    "scale": "1.7",
    "honors_gpa_from": "1.9",
    "honors_gpa_to": "2.2",
    "ap_ib_gpa_from": "2.4",
    "ap_ib_gpa_to": "2.7"
  },
  {
    "id": 10,
    "letter_grade": "D+",
    "percent_grade_from": 67,
    "percent_grade_to": 69,
    "scale": "1.3",
    "honors_gpa_from": "1.6",
    "honors_gpa_to": "1.8",
    "ap_ib_gpa_from": "2.1",
    "ap_ib_gpa_to": "2.3"
  },
  {
    "id": 11,
    "letter_grade": "D",
    "percent_grade_from": 65,
    "percent_grade_to": 66,
    "scale": "1.0",
    "honors_gpa_from": "0.1",
    "honors_gpa_to": "1.5",
    "ap_ib_gpa_from": "0.1",
    "ap_ib_gpa_to": "2.0"
  },
  {
    "id": 12,
    "letter_grade": "E/F",
    "percent_grade_from": 0,
    "percent_grade_to": 65,
    "scale": "0.0",
    "honors_gpa_from": "0.0",
    "honors_gpa_to": null,
    "ap_ib_gpa_from": "0.0",
    "ap_ib_gpa_to": null
  },
  {
    "id": 1,
    "letter_grade": "A+",
    "percent_grade_from": 97,
    "percent_grade_to": 100,
    "scale": "4.0",
    "honors_gpa_from": "4.5",
    "honors_gpa_to": "4.5",
    "ap_ib_gpa_from": "5.0",
    "ap_ib_gpa_to": "5.0"
  }
]
</code>```

答:
angular.module('app', []).controller('MyController', ['$scope', function($scope) {
    $scope.gpa = {grade_percent:68};

    var data = [
  {
    "id": 2,
    "letter_grade": "A",
    "percent_grade_from": 93,
    "percent_grade_to": 96,
    "scale": "4.0",
    "honors_gpa_from": "4.3",
    "honors_gpa_to": "4.4",
    "ap_ib_gpa_from": "4.8",
    "ap_ib_gpa_to": "4.9"
  },
  {
    "id": 3,
    "letter_grade": "A-",
    "percent_grade_from": 90,
    "percent_grade_to": 92,
    "scale": "3.7",
    "honors_gpa_from": "3.9",
    "honors_gpa_to": "4.2",
    "ap_ib_gpa_from": "4.4",
    "ap_ib_gpa_to": "4.7"
  },
  {
    "id": 4,
    "letter_grade": "B+",
    "percent_grade_from": 87,
    "percent_grade_to": 89,
    "scale": "3.3",
    "honors_gpa_from": "3.6",
    "honors_gpa_to": "3.8",
    "ap_ib_gpa_from": "4.1",
    "ap_ib_gpa_to": "4.3"
  },
  {
    "id": 5,
    "letter_grade": "B",
    "percent_grade_from": 83,
    "percent_grade_to": 86,
    "scale": "3.0",
    "honors_gpa_from": "3.3",
    "honors_gpa_to": "3.5",
    "ap_ib_gpa_from": "3.8",
    "ap_ib_gpa_to": "4.0"
  },
  {
    "id": 6,
    "letter_grade": "B-",
    "percent_grade_from": 80,
    "percent_grade_to": 82,
    "scale": "2.7",
    "honors_gpa_from": "2.0",
    "honors_gpa_to": "3.2",
    "ap_ib_gpa_from": "3.4",
    "ap_ib_gpa_to": "3.7"
  },
  {
    "id": 7,
    "letter_grade": "C+",
    "percent_grade_from": 77,
    "percent_grade_to": 79,
    "scale": "2.3",
    "honors_gpa_from": "2.6",
    "honors_gpa_to": "2.8",
    "ap_ib_gpa_from": "3.1",
    "ap_ib_gpa_to": "3.3"
  },
  {
    "id": 8,
    "letter_grade": "C",
    "percent_grade_from": 73,
    "percent_grade_to": 76,
    "scale": "2.0",
    "honors_gpa_from": "2.3",
    "honors_gpa_to": "2.5",
    "ap_ib_gpa_from": "2.8",
    "ap_ib_gpa_to": "3.0"
  },
  {
    "id": 9,
    "letter_grade": "C-",
    "percent_grade_from": 70,
    "percent_grade_to": 72,
    "scale": "1.7",
    "honors_gpa_from": "1.9",
    "honors_gpa_to": "2.2",
    "ap_ib_gpa_from": "2.4",
    "ap_ib_gpa_to": "2.7"
  },
  {
    "id": 10,
    "letter_grade": "D+",
    "percent_grade_from": 67,
    "percent_grade_to": 69,
    "scale": "1.3",
    "honors_gpa_from": "1.6",
    "honors_gpa_to": "1.8",
    "ap_ib_gpa_from": "2.1",
    "ap_ib_gpa_to": "2.3"
  },
  {
    "id": 11,
    "letter_grade": "D",
    "percent_grade_from": 65,
    "percent_grade_to": 66,
    "scale": "1.0",
    "honors_gpa_from": "0.1",
    "honors_gpa_to": "1.5",
    "ap_ib_gpa_from": "0.1",
    "ap_ib_gpa_to": "2.0"
  },
  {
    "id": 12,
    "letter_grade": "E/F",
    "percent_grade_from": 0,
    "percent_grade_to": 65,
    "scale": "0.0",
    "honors_gpa_from": "0.0",
    "honors_gpa_to": null,
    "ap_ib_gpa_from": "0.0",
    "ap_ib_gpa_to": null
  },
  {
    "id": 1,
    "letter_grade": "A+",
    "percent_grade_from": 97,
    "percent_grade_to": 100,
    "scale": "4.0",
    "honors_gpa_from": "4.5",
    "honors_gpa_to": "4.5",
    "ap_ib_gpa_from": "5.0",
    "ap_ib_gpa_to": "5.0"
  }
];
    $scope.find = function(){
      $scope.gpa.grade_scale = (data.filter(function(x){
        return x.percent_grade_from <= $scope.gpa.grade_percent && x.percent_grade_to >= $scope.gpa.grade_percent;
      })[0] || {}).scale;
    }
    $scope.find();
}])```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="//code.angularjs.org/snapshot/angular.min.js"></script>

<div ng-app='app' ng-controller="MyController">
    <input type="text" ng-model="gpa.grade_percent" aria-label="Grade" ng-change='find()'>
    <br/>
    <span ng-bind='gpa.grade_scale'></span>
</div></code>```

Body:
I have an input field

<md-input-container ng-if="gpa.grade_type==2">
    <input type="text" ng-model="gpa.grade_percent" aria-label="Grade">
</md-input-container>

I want to check the gpa.grade_percent "percent_grade_from": 93 - "percent_grade_to": 96, value in JSON in which interval it fits
so that I have to show the interval related scale in the next field.

JSON :

[
  {
    "id": 2,
    "letter_grade": "A",
    "percent_grade_from": 93,
    "percent_grade_to": 96,
    "scale": "4.0",
    "honors_gpa_from": "4.3",
    "honors_gpa_to": "4.4",
    "ap_ib_gpa_from": "4.8",
    "ap_ib_gpa_to": "4.9"
  },
  {
    "id": 3,
    "letter_grade": "A-",
    "percent_grade_from": 90,
    "percent_grade_to": 92,
    "scale": "3.7",
    "honors_gpa_from": "3.9",
    "honors_gpa_to": "4.2",
    "ap_ib_gpa_from": "4.4",
    "ap_ib_gpa_to": "4.7"
  },
  {
    "id": 4,
    "letter_grade": "B+",
    "percent_grade_from": 87,
    "percent_grade_to": 89,
    "scale": "3.3",
    "honors_gpa_from": "3.6",
    "honors_gpa_to": "3.8",
    "ap_ib_gpa_from": "4.1",
    "ap_ib_gpa_to": "4.3"
  },
  {
    "id": 5,
    "letter_grade": "B",
    "percent_grade_from": 83,
    "percent_grade_to": 86,
    "scale": "3.0",
    "honors_gpa_from": "3.3",
    "honors_gpa_to": "3.5",
    "ap_ib_gpa_from": "3.8",
    "ap_ib_gpa_to": "4.0"
  },
  {
    "id": 6,
    "letter_grade": "B-",
    "percent_grade_from": 80,
    "percent_grade_to": 82,
    "scale": "2.7",
    "honors_gpa_from": "2.0",
    "honors_gpa_to": "3.2",
    "ap_ib_gpa_from": "3.4",
    "ap_ib_gpa_to": "3.7"
  },
  {
    "id": 7,
    "letter_grade": "C+",
    "percent_grade_from": 77,
    "percent_grade_to": 79,
    "scale": "2.3",
    "honors_gpa_from": "2.6",
    "honors_gpa_to": "2.8",
    "ap_ib_gpa_from": "3.1",
    "ap_ib_gpa_to": "3.3"
  },
  {
    "id": 8,
    "letter_grade": "C",
    "percent_grade_from": 73,
    "percent_grade_to": 76,
    "scale": "2.0",
    "honors_gpa_from": "2.3",
    "honors_gpa_to": "2.5",
    "ap_ib_gpa_from": "2.8",
    "ap_ib_gpa_to": "3.0"
  },
  {
    "id": 9,
    "letter_grade": "C-",
    "percent_grade_from": 70,
    "percent_grade_to": 72,
    "scale": "1.7",
    "honors_gpa_from": "1.9",
    "honors_gpa_to": "2.2",
    "ap_ib_gpa_from": "2.4",
    "ap_ib_gpa_to": "2.7"
  },
  {
    "id": 10,
    "letter_grade": "D+",
    "percent_grade_from": 67,
    "percent_grade_to": 69,
    "scale": "1.3",
    "honors_gpa_from": "1.6",
    "honors_gpa_to": "1.8",
    "ap_ib_gpa_from": "2.1",
    "ap_ib_gpa_to": "2.3"
  },
  {
    "id": 11,
    "letter_grade": "D",
    "percent_grade_from": 65,
    "percent_grade_to": 66,
    "scale": "1.0",
    "honors_gpa_from": "0.1",
    "honors_gpa_to": "1.5",
    "ap_ib_gpa_from": "0.1",
    "ap_ib_gpa_to": "2.0"
  },
  {
    "id": 12,
    "letter_grade": "E/F",
    "percent_grade_from": 0,
    "percent_grade_to": 65,
    "scale": "0.0",
    "honors_gpa_from": "0.0",
    "honors_gpa_to": null,
    "ap_ib_gpa_from": "0.0",
    "ap_ib_gpa_to": null
  },
  {
    "id": 1,
    "letter_grade": "A+",
    "percent_grade_from": 97,
    "percent_grade_to": 100,
    "scale": "4.0",
    "honors_gpa_from": "4.5",
    "honors_gpa_to": "4.5",
    "ap_ib_gpa_from": "5.0",
    "ap_ib_gpa_to": "5.0"
  }
]

Body:
angular.module('app', []).controller('MyController', ['$scope', function($scope) {
    $scope.gpa = {grade_percent:68};

    var data = [
  {
    "id": 2,
    "letter_grade": "A",
    "percent_grade_from": 93,
    "percent_grade_to": 96,
    "scale": "4.0",
    "honors_gpa_from": "4.3",
    "honors_gpa_to": "4.4",
    "ap_ib_gpa_from": "4.8",
    "ap_ib_gpa_to": "4.9"
  },
  {
    "id": 3,
    "letter_grade": "A-",
    "percent_grade_from": 90,
    "percent_grade_to": 92,
    "scale": "3.7",
    "honors_gpa_from": "3.9",
    "honors_gpa_to": "4.2",
    "ap_ib_gpa_from": "4.4",
    "ap_ib_gpa_to": "4.7"
  },
  {
    "id": 4,
    "letter_grade": "B+",
    "percent_grade_from": 87,
    "percent_grade_to": 89,
    "scale": "3.3",
    "honors_gpa_from": "3.6",
    "honors_gpa_to": "3.8",
    "ap_ib_gpa_from": "4.1",
    "ap_ib_gpa_to": "4.3"
  },
  {
    "id": 5,
    "letter_grade": "B",
    "percent_grade_from": 83,
    "percent_grade_to": 86,
    "scale": "3.0",
    "honors_gpa_from": "3.3",
    "honors_gpa_to": "3.5",
    "ap_ib_gpa_from": "3.8",
    "ap_ib_gpa_to": "4.0"
  },
  {
    "id": 6,
    "letter_grade": "B-",
    "percent_grade_from": 80,
    "percent_grade_to": 82,
    "scale": "2.7",
    "honors_gpa_from": "2.0",
    "honors_gpa_to": "3.2",
    "ap_ib_gpa_from": "3.4",
    "ap_ib_gpa_to": "3.7"
  },
  {
    "id": 7,
    "letter_grade": "C+",
    "percent_grade_from": 77,
    "percent_grade_to": 79,
    "scale": "2.3",
    "honors_gpa_from": "2.6",
    "honors_gpa_to": "2.8",
    "ap_ib_gpa_from": "3.1",
    "ap_ib_gpa_to": "3.3"
  },
  {
    "id": 8,
    "letter_grade": "C",
    "percent_grade_from": 73,
    "percent_grade_to": 76,
    "scale": "2.0",
    "honors_gpa_from": "2.3",
    "honors_gpa_to": "2.5",
    "ap_ib_gpa_from": "2.8",
    "ap_ib_gpa_to": "3.0"
  },
  {
    "id": 9,
    "letter_grade": "C-",
    "percent_grade_from": 70,
    "percent_grade_to": 72,
    "scale": "1.7",
    "honors_gpa_from": "1.9",
    "honors_gpa_to": "2.2",
    "ap_ib_gpa_from": "2.4",
    "ap_ib_gpa_to": "2.7"
  },
  {
    "id": 10,
    "letter_grade": "D+",
    "percent_grade_from": 67,
    "percent_grade_to": 69,
    "scale": "1.3",
    "honors_gpa_from": "1.6",
    "honors_gpa_to": "1.8",
    "ap_ib_gpa_from": "2.1",
    "ap_ib_gpa_to": "2.3"
  },
  {
    "id": 11,
    "letter_grade": "D",
    "percent_grade_from": 65,
    "percent_grade_to": 66,
    "scale": "1.0",
    "honors_gpa_from": "0.1",
    "honors_gpa_to": "1.5",
    "ap_ib_gpa_from": "0.1",
    "ap_ib_gpa_to": "2.0"
  },
  {
    "id": 12,
    "letter_grade": "E/F",
    "percent_grade_from": 0,
    "percent_grade_to": 65,
    "scale": "0.0",
    "honors_gpa_from": "0.0",
    "honors_gpa_to": null,
    "ap_ib_gpa_from": "0.0",
    "ap_ib_gpa_to": null
  },
  {
    "id": 1,
    "letter_grade": "A+",
    "percent_grade_from": 97,
    "percent_grade_to": 100,
    "scale": "4.0",
    "honors_gpa_from": "4.5",
    "honors_gpa_to": "4.5",
    "ap_ib_gpa_from": "5.0",
    "ap_ib_gpa_to": "5.0"
  }
];
    $scope.find = function(){
      $scope.gpa.grade_scale = (data.filter(function(x){
        return x.percent_grade_from <= $scope.gpa.grade_percent && x.percent_grade_to >= $scope.gpa.grade_percent;
      })[0] || {}).scale;
    }
    $scope.find();
}])

<script src="//code.angularjs.org/snapshot/angular.min.js"></script>

<div ng-app='app' ng-controller="MyController">
    <input type="text" ng-model="gpa.grade_percent" aria-label="Grade" ng-change='find()'>
    <br/>
    <span ng-bind='gpa.grade_scale'></span>
</div>


问:
Oracle SQL- Update Query with Case Statement Missing Keyword Error
I'm extremely new to SQL (started learning 3 days ago), so I'm assuming I have some horrendous syntax errors in my code.

I've been at it since yesterday, trying to create an update query that uses cases to modify the value column based on the following conditions:

When value contains the letter 'a', make value uppercase.

When value contains the letter 'd', but doesn't contain the letter 'a', make value lowercase.

When value doesn't meet the conditions above, change the first and last letters from value to 1 and 2.

I have tried to do this a bunch of different ways, but I always end up with some kind of error. This code returns Missing Keyword Error:

```<code>UPDATE t1
SET value =
CASE   WHEN value LIKE '%a%' THEN SET value = UPPER(value)
       WHEN value LIKE '%d%' AND value NOT LIKE '%a' THEN SET value = LOWER(value)
       ELSE REPLACE(value,'_%','1') AND REPLACE(value,'%_','2')
END
Where value IS NOT NULL;
</code>```

答:
there are many syntex error in Case statment you cant use again SET operation and you cant use separated replace

change

1.SET value = UPPER(value) to  UPPER(value)
2.SET value = LOWER(value) to LOWER(value) and
3. remove secondreplace like this

```<code>UPDATE t1
SET value =
CASE   WHEN value LIKE '%a%' THEN SET UPPER(value)
       WHEN value LIKE '%d%' AND value NOT LIKE '%a' THEN LOWER(value)
       ELSE REAPLACE(REPLACE(value,'_%','1'),'%_',2)
END
Where value IS NOT NULL;
</code>```

Body:
I'm extremely new to SQL (started learning 3 days ago), so I'm assuming I have some horrendous syntax errors in my code.

I've been at it since yesterday, trying to create an update query that uses cases to modify the value column based on the following conditions:

When value contains the letter 'a', make value uppercase.

When value contains the letter 'd', but doesn't contain the letter 'a', make value lowercase.

When value doesn't meet the conditions above, change the first and last letters from value to 1 and 2.

I have tried to do this a bunch of different ways, but I always end up with some kind of error. This code returns Missing Keyword Error:

UPDATE t1
SET value =
CASE   WHEN value LIKE '%a%' THEN SET value = UPPER(value)
       WHEN value LIKE '%d%' AND value NOT LIKE '%a' THEN SET value = LOWER(value)
       ELSE REPLACE(value,'_%','1') AND REPLACE(value,'%_','2')
END
Where value IS NOT NULL;

Body:
there are many syntex error in Case statment you cant use again SET operation and you cant use separated replace

change

1.SET value = UPPER(value) to  UPPER(value)
2.SET value = LOWER(value) to LOWER(value) and
3. remove secondreplace like this

UPDATE t1
SET value =
CASE   WHEN value LIKE '%a%' THEN SET UPPER(value)
       WHEN value LIKE '%d%' AND value NOT LIKE '%a' THEN LOWER(value)
       ELSE REAPLACE(REPLACE(value,'_%','1'),'%_',2)
END
Where value IS NOT NULL;


问:
Connect from a Docker container to port of another docker container
I have two docker containers running on a linux host.

One with a DATABASE and one with an APPLICATION.

How can I connect from container APPLICATION to container DATABASE port 5432?

For example:
I start DATABASE container and bind port 5432 to hosts localhost with "-p5432:5432. But how can I acces this port from APPLICATION? I cannot bind port 5432 to host localhost because this port is now already used.

Docker version 1.12.6

update

I used now

```<code>sudo docker network create --subnet=172.20.0.0/16 --gateway=172.20.0.100   --ip-range=172.20.1.0/24 my-network
sudo docker run --name postgres  --network=my-network --ip=172.20.0.10 -d postgres
sudo docker run --name application --network=my-network --ip=172.20.0.15 -d application
</code>```

and configured app in APPLICATION container to look for ip 172.20.0.10

https://docs.docker.com/engine/userguide/networking/work-with-networks/

答:
You can use docker link to link to running containers ... like below and use alias name as ip address. You can do same using docker-compose as well.

$ docker run -d -P --name application --link db-image:db application-image

use 'db' as host name in your application.

You can also give your host ip to application container as db end point. It will work.

Body:
I have two docker containers running on a linux host.

One with a DATABASE and one with an APPLICATION.

How can I connect from container APPLICATION to container DATABASE port 5432?

For example:
I start DATABASE container and bind port 5432 to hosts localhost with "-p5432:5432. But how can I acces this port from APPLICATION? I cannot bind port 5432 to host localhost because this port is now already used.

Docker version 1.12.6

update

I used now

sudo docker network create --subnet=172.20.0.0/16 --gateway=172.20.0.100   --ip-range=172.20.1.0/24 my-network
sudo docker run --name postgres  --network=my-network --ip=172.20.0.10 -d postgres
sudo docker run --name application --network=my-network --ip=172.20.0.15 -d application

and configured app in APPLICATION container to look for ip 172.20.0.10

https://docs.docker.com/engine/userguide/networking/work-with-networks/


问:
How to remove null value and filled by the next Column Value
I am loading data from multiple source to a destination table using SSIS . The destination table only have 5 Columns but we have 11 value (Columns) need to load. So I load into second row and Third row with the same ID .

The Question is not every ID have 11 value , Most of them less than 11 . So there are Null and 0 Amount in the table . The requirement is we have to use the value name and Amount in order . For example if Value Amount3 = Null . Then we should use ValueName 4 and ValueAmount4 to fill ValueAmount3 and ValueName3.

Column Name
ID  |ValueAmount1 |ValueName1 |ValueAmount2 |ValueName2 |ValueAmount3 |ValueName3 |ValueAmount4 |ValueName4 |ValueAmount 5 |ValueName5

Any suggestions will be appreciate !

答: Load all the data into a staging table, and then use a stored procedure to populate the final table from the staging table, and use COALESCE in the stored procedure to replace NULLS with other columns, like COALESCE(ValueAmount3, ValueAmount4)


问:
what is typeof((c) + 1) in C
I came across an expression in C like

```<code>typeof((c) + 1) _tmp = c;
</code>```

What exactly does this mean?

Thanks for the reply.

Just one doubt? What if the type of c is struct instead of the primitive types, then what will +1 do?

答:
Typeof returns a type, and is evaluated at compile time.

The whole statement means declare a variable tmp with the same type as c (usually).

It might declare a related or different type, since the type of c+1 can be different to c.  (this is more likely in c++).

Title: what is typeof((c) + 1) in C

Body:
I came across an expression in C like

typeof((c) + 1) _tmp = c;

What exactly does this mean?

Thanks for the reply.

Just one doubt? What if the type of c is struct instead of the primitive types, then what will +1 do?


问:
How to correctly set-up mockito in the test class?
I have written the tests   handleFirebaseMessagesBigText() and handleFirebaseMessagesBigPicture() using Mockito.
   Under @Before , in the function init() , if I don't comment out the last 2 lines, these 2 tests and all my other tests also fail for some reason. If I comment out these 2 lines, the 2 tests above fail. I'm not able to make these tests work. How do I fix this?

```<code>@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    private Context context;

    @Mock
    private HandleFirebaseMessages handleFirebaseMessages;

    @Rule
    public ActivityTestRule<MainActivity> activityTestRule =
            new ActivityTestRule<>(MainActivity.class);

    @Before
    public void init() {
        context = InstrumentationRegistry.getTargetContext();
        //MockitoAnnotations.initMocks(this);
        //handleFirebaseMessages = new HandleFirebaseMessages();
    }

 @Test
    public void handleFirebaseMessagesBigText() {
        RemoteMessage remoteMessage = new RemoteMessage.Builder("token").addData("type","1").build();
        handleFirebaseMessages.onMessageReceived(remoteMessage);
        Map<String,String> data = new HashMap<>() ;
        data.put("type","1");
        Mockito.verify(handleFirebaseMessages).buildNotificationBigText(data);
    }

    @Test
    public void handleFirebaseMessagesBigPicture() {
        RemoteMessage remoteMessage = new RemoteMessage.Builder("token").addData("type","2").build();
        handleFirebaseMessages.onMessageReceived(remoteMessage);
        Map<String,String> data = new HashMap<>() ;
        data.put("type","2");
                 Mockito.verify(handleFirebaseMessages).buildNotificationBigPicture(data);
    }
}
</code>```

EDIT
I'm getting the following error for both my test methods:

```<code>  java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
</code>```

As you can see in the code, I'm passing the key value pair "type"-"1" in my test functions to onMessageReceived() . And subsequently I get these 2 errors.
     However, if I use the firebase console to send a message with this exact key-value pair, everything works all right. So I'm guessing there's something wrong with the way I'm using RemoteMessage to send my key value pair to onMessageReceived().

答:
You are already mocking your instance variable handleFirebaseMessages with the @Mock annotation, so you do not need to create an instance yourself (Mockito will).

Try with this:

```<code>@Before
public void init() {
    context = InstrumentationRegistry.getTargetContext();
    MockitoAnnotations.initMocks(this);
    //handleFirebaseMessages = new HandleFirebaseMessages();
}
</code>```

Body:
I have written the tests   handleFirebaseMessagesBigText() and handleFirebaseMessagesBigPicture() using Mockito.
   Under @Before , in the function init() , if I don't comment out the last 2 lines, these 2 tests and all my other tests also fail for some reason. If I comment out these 2 lines, the 2 tests above fail. I'm not able to make these tests work. How do I fix this?

@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    private Context context;

    @Mock
    private HandleFirebaseMessages handleFirebaseMessages;

    @Rule
    public ActivityTestRule<MainActivity> activityTestRule =
            new ActivityTestRule<>(MainActivity.class);

    @Before
    public void init() {
        context = InstrumentationRegistry.getTargetContext();
        //MockitoAnnotations.initMocks(this);
        //handleFirebaseMessages = new HandleFirebaseMessages();
    }

 @Test
    public void handleFirebaseMessagesBigText() {
        RemoteMessage remoteMessage = new RemoteMessage.Builder("token").addData("type","1").build();
        handleFirebaseMessages.onMessageReceived(remoteMessage);
        Map<String,String> data = new HashMap<>() ;
        data.put("type","1");
        Mockito.verify(handleFirebaseMessages).buildNotificationBigText(data);
    }

    @Test
    public void handleFirebaseMessagesBigPicture() {
        RemoteMessage remoteMessage = new RemoteMessage.Builder("token").addData("type","2").build();
        handleFirebaseMessages.onMessageReceived(remoteMessage);
        Map<String,String> data = new HashMap<>() ;
        data.put("type","2");
                 Mockito.verify(handleFirebaseMessages).buildNotificationBigPicture(data);
    }
}

EDIT
I'm getting the following error for both my test methods:

  java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

As you can see in the code, I'm passing the key value pair "type"-"1" in my test functions to onMessageReceived() . And subsequently I get these 2 errors.
     However, if I use the firebase console to send a message with this exact key-value pair, everything works all right. So I'm guessing there's something wrong with the way I'm using RemoteMessage to send my key value pair to onMessageReceived().

Body:
You are already mocking your instance variable handleFirebaseMessages with the @Mock annotation, so you do not need to create an instance yourself (Mockito will).

Try with this:

@Before
public void init() {
    context = InstrumentationRegistry.getTargetContext();
    MockitoAnnotations.initMocks(this);
    //handleFirebaseMessages = new HandleFirebaseMessages();
}


问:
Is using a math class method in a loop condition slow?
if i have a for loop for example and and i want to use something like Math.round() to round the number but i only need to round the number one time(i.e the number doesn't change throughout the loop) is it better to store it into a variable and then use the variable to in the condition or does it not matter?

```<code> for (int i = 0;i < Math.Round(x);i++)
   {
   //Some code
   }
</code>```

vs

```<code> for (int i = 0,roundedX = Math.Round(X); i<roundedX;i++)
  {
  //Some code
  }
</code>```

答:
The compiler will evaluate the termination condition on every loop iteration.

The compiler and the JITter might hoist some expression or part of an expression outside the loop if it deems it is invariant, meaning it doesn't change. This, however, is usually only done with simpler expressions.

If the Math.Round(X) expression could've been done without an actual method call then perhaps but in this particular case the rounding will happen on each loop iteration.

As such, if you're at last line defense for performance problems, you might consider moving this out and into a variable:

```<code>int goal = (int)Math.Round(X);
for (int i = 0; i < goal; i++)
    ...
</code>```

As this will call the Math.Round method only once, you only get the performance hit once.

Note that if X changes as part of the loop, then obviously you want to keep your original code.

Body:
if i have a for loop for example and and i want to use something like Math.round() to round the number but i only need to round the number one time(i.e the number doesn't change throughout the loop) is it better to store it into a variable and then use the variable to in the condition or does it not matter?

 for (int i = 0;i < Math.Round(x);i++)
   {
   //Some code
   }

vs

 for (int i = 0,roundedX = Math.Round(X); i<roundedX;i++)
  {
  //Some code
  }

Body:
The compiler will evaluate the termination condition on every loop iteration.

The compiler and the JITter might hoist some expression or part of an expression outside the loop if it deems it is invariant, meaning it doesn't change. This, however, is usually only done with simpler expressions.

If the Math.Round(X) expression could've been done without an actual method call then perhaps but in this particular case the rounding will happen on each loop iteration.

As such, if you're at last line defense for performance problems, you might consider moving this out and into a variable:

int goal = (int)Math.Round(X);
for (int i = 0; i < goal; i++)
    ...

As this will call the Math.Round method only once, you only get the performance hit once.

Note that if X changes as part of the loop, then obviously you want to keep your original code.


问:
Want program to continue even when there is an exception
I have searched a few times but I kinda, didnt found what i exactly wanted.

I was working out with exceptional handling (try/catch), where i found this obstacle. If the program finds an exception, it terminated whatsoever.

I tried calling a function in the catch part, but it still terminates.

```<code>void exception_handle() //This is for handling exception if user inputs a char instead of int//
{
user_play uplay;
try
 {
    uplay.usersentry();
 }
catch(std::runtime_error& e)
 {
    cout<<"Input a string bro, not a character"<<endl;
    user_input();
 }
}
</code>```

Here is the class:

```<code>class user_play //this class is for letting user play the game by allowing them to enter desired number in the desired empty space//
{
 public:
 void usersentry()
  {
    int tempdata;
    retry:
     cout<<"\n\n Enter the row and coloumn where you want to enter data"<<endl;
     cin>>i>>j;
        if (i>=1 && i<=9 && j>=1 && j<=9)
        {
            cout<<"\n Enter your desired value to put in that place"<<endl;
            cin>>tempdata;
            if(tempdata>=1 && tempdata<=9)
            {
                data=tempdata;
            }
            else
            {
                throw std::runtime_error("Soduku contains numbers from 1 to 9 only.Please try again");
                loops++;
            }
        }
        else
        {
            throw std::runtime_error("Soduku row exists between 1 and 9 only.Please try again");
            loops++;
        }
   }
};
</code>```

Here is the function(It's incomplete as i am trying to debugg)

```<code>int user_input() //this one is for taking correct value from user and storing it in its respective place//
{
a=0;
//Object Declaration//
rowrules rr;
columnrules cr;

//for handling the program exceptions
exception_handle();

//rules for row and column
//rr.rrules();
//cr.crules();
//ruleselect();
//i--;
//j--;
if(a==0)
{
    soduku[i-1][j-1]=data;
  return soduku[i-1][j-1];
}
else
 {
    user_input();
 }
}
</code>```

here as you see i tried calling the function in catch part but still the program terminated.Am I missing something basic?? Or is there any other solution/method/logic?
Thanks!

答:
It is not possible to continue execution from the place where C++ exception is thrown. C++ exceptions are not designed for that. But it is possible to repeat the code you want repeated if the exception happens:

```<code>for (bool success = false; !success; )
{
    try
    {
        <some code that should be repeated if exception happens>

        success = true;
    }
    catch (...)
    {
    }
}
</code>```

Note that in general case it is a bad idea to do absolutely nothing if exception happens. At least write something down in some log file, if you have it.

Body:
I have searched a few times but I kinda, didnt found what i exactly wanted.

I was working out with exceptional handling (try/catch), where i found this obstacle. If the program finds an exception, it terminated whatsoever.

I tried calling a function in the catch part, but it still terminates.

void exception_handle() //This is for handling exception if user inputs a char instead of int//
{
user_play uplay;
try
 {
    uplay.usersentry();
 }
catch(std::runtime_error& e)
 {
    cout<<"Input a string bro, not a character"<<endl;
    user_input();
 }
}

Here is the class:

class user_play //this class is for letting user play the game by allowing them to enter desired number in the desired empty space//
{
 public:
 void usersentry()
  {
    int tempdata;
    retry:
     cout<<"\n\n Enter the row and coloumn where you want to enter data"<<endl;
     cin>>i>>j;
        if (i>=1 && i<=9 && j>=1 && j<=9)
        {
            cout<<"\n Enter your desired value to put in that place"<<endl;
            cin>>tempdata;
            if(tempdata>=1 && tempdata<=9)
            {
                data=tempdata;
            }
            else
            {
                throw std::runtime_error("Soduku contains numbers from 1 to 9 only.Please try again");
                loops++;
            }
        }
        else
        {
            throw std::runtime_error("Soduku row exists between 1 and 9 only.Please try again");
            loops++;
        }
   }
};

Here is the function(It's incomplete as i am trying to debugg)

int user_input() //this one is for taking correct value from user and storing it in its respective place//
{
a=0;
//Object Declaration//
rowrules rr;
columnrules cr;

//for handling the program exceptions
exception_handle();

//rules for row and column
//rr.rrules();
//cr.crules();
//ruleselect();
//i--;
//j--;
if(a==0)
{
    soduku[i-1][j-1]=data;
  return soduku[i-1][j-1];
}
else
 {
    user_input();
 }
}

here as you see i tried calling the function in catch part but still the program terminated.Am I missing something basic?? Or is there any other solution/method/logic?
Thanks!

Body:
It is not possible to continue execution from the place where C++ exception is thrown. C++ exceptions are not designed for that. But it is possible to repeat the code you want repeated if the exception happens:

for (bool success = false; !success; )
{
    try
    {
        <some code that should be repeated if exception happens>

        success = true;
    }
    catch (...)
    {
    }
}

Note that in general case it is a bad idea to do absolutely nothing if exception happens. At least write something down in some log file, if you have it.


问:
androidplot 1.4.3 redraw run-time analysis with JNI getY (idx) access
i did evaluate the run-time performance of a 6 XYSeries plot setup (500 X axis samples) on a nexus 7 2013 with simple synthesized sine waves in the getY (idx) functs and compared it to a JNI getY (idx) based setup where the JNI C++ code simply fetched the data from a buffer within the JNI capsule

here is a simplified setup for the synthesized sine wave generation (example shows one XYSeries)

```<code>public static int  DatCnt = 0 ;
       static long DatSav ;

@Override
public double GetY (int idx) // being called by super.getY (idx), which implements XYSeries
{
  long t0 = 0 ;

  if (DatCnt >    0) { DatCnt-- ; t0 = System.nanoTime () ; }
  if (DatCnt == 499)   DatSav   = t0 ;

  double dat = Sin (idx) * 45 + 50 ;

//if (DatCnt >    0 &&
//    DatCnt <   10) {
//  Log.i ("com.efiLabs.PlotXYtst", String.format ("dat0 %6d %d", (System.nanoTime () - t0) / 1000, DatCnt)) ;
//}
  if (DatCnt ==   1) {                                                                   ActPlotNew0.Tsum += t0 - DatSav ;
    Log.i ("com.efiLabs.PlotXYtst", String.format ("dat0 %6d %6d", (t0 - DatSav) / 1000, ActPlotNew0.Tsum / 1000)) ;
  }
  return dat ;
//return Sin (idx) * 45 + 50 ;
}
</code>```

and this is the android monitor output

```<code>06-04 16:14:40.707 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onDown x_1493 y_523
06-04 16:14:40.797 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_23
06-04 16:14:40.797 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 233989457389
06-04 16:14:40.861 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat0  33874  33874
06-04 16:14:40.901 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat1  26428  60302
06-04 16:14:40.938 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat2  24627  84930
06-04 16:14:40.974 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat3  25299 110229
06-04 16:14:41.010 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat4  24047 134277
06-04 16:14:41.046 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat5  25299 159576
06-04 16:14:41.069 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_517
06-04 16:14:41.069 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 272247
06-04 16:14:41.129 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat0  24322  24322
06-04 16:14:41.165 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat1  24536  48858
06-04 16:14:41.200 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat2  24688  73547
06-04 16:14:41.236 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat3  24414  97961
06-04 16:14:41.271 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat4  23895 121856
06-04 16:14:41.305 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat5  23834 145690
06-04 16:14:41.326 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_37
06-04 16:14:41.326 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 256622
06-04 16:14:41.387 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat0  23834  23834
06-04 16:14:41.429 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat1  30395  54229
06-04 16:14:41.473 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat2  28411  82641
06-04 16:14:41.507 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat3  23406 106048
06-04 16:14:41.542 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat4  23803 129852
06-04 16:14:41.576 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat5  24108 153961
</code>```

a vertical scroll will start the loop with the DatUpd () functs being called periodically

```<code>public static long Tstart, Tsum ;

public synchronized void DataUpd ()
{

  LogI (String.format ("sum %d", (System.nanoTime () - Tstart) / 1000)) ;

  DataY_0.DatCnt = 500 ;
  DataY_1.DatCnt = 500 ;
  DataY_2.DatCnt = 500 ;
  DataY_3.DatCnt = 500 ;
  DataY_4.DatCnt = 500 ;
  DataY_5.DatCnt = 500 ;

  Tstart = System.nanoTime () ;
  Tsum   = 0 ;

  Plot.redraw () ;
}
</code>```

the "dat3 25299 110229" shows the exex times for each series (dat0 - dat5), whereas the 1st number is the individual time accumulation from the x-data 0 to 500, and the 2nd is a running time tally ... 25299 us for the dat3 series and 110299 us for dat0 to dat3 and so on ... an average data fetch time per ZYSeries is about 25 ms

the total sum of 272247 us is the time from the 1st DatUpd () call to the next one in the scroll operation ... i didn't have a hook into when the plot redraw process was complete

the total getY (idx) data fetch time for all 6 XYSeries is 159576 us and the total redraw cycle time 272247 us ... 272247 - 159576 = 112671 us

of course i do not have any idea of the percentage of the remaining time (after the fetch time) of 112671 us, which is androidplot time and which is scroll gesture processing

and now to the C++ JNI setup timing

```<code>06-04 17:09:39.783 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onDown x_1620 y_497
06-04 17:09:39.881 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_16
06-04 17:09:39.882 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 25543273
06-04 17:09:39.947 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rdif  36865  36865
06-04 17:09:39.995 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rpm   36956  73822
06-04 17:09:40.032 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: tdif  36224 110046
06-04 17:09:40.085 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext0  42205 152252
06-04 17:09:40.138 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext1  41778 194030
06-04 17:09:40.202 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: raw2  53955 247985
06-04 17:09:40.226 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_724
06-04 17:09:40.226 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 344085
06-04 17:09:40.293 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rdif  36956  36956
06-04 17:09:40.341 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rpm   36651  73608
06-04 17:09:40.377 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: tdif  36315 109924
06-04 17:09:40.429 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext0  40954 150878
06-04 17:09:40.481 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext1  40802 191680
06-04 17:09:40.534 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: raw2  41015 232696
06-04 17:09:40.555 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_4
06-04 17:09:40.555 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 329620
06-04 17:09:40.619 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rdif  36712  36712
06-04 17:09:40.666 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rpm   36499  73211
06-04 17:09:40.702 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: tdif  36163 109375
06-04 17:09:40.779 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext0  63323 172698
06-04 17:09:40.836 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext1  42266 214965
06-04 17:09:40.888 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: raw2  41259 256225
</code>```

comparison :

accumulated fetch time is 247985 us

the sine synthesized data fetches take an average 25 ms / series whereas the C++ JNI data fetches take about 40 ms ... 15 ms longer, an increase of 60 % over the sine wave synthesis example

the percentage of the getY (idx) synthesized sine wave generation time portion is unknown and so is what else is happening inside androidplot from one getY (idx) to the next one

25 ms / 500 x-samples is 50 us, 15 ms / 500 x-samples = 30 us   ... assuming that the sine calculation can't take the majority of the 50 us i would say that a single getY (idx) call processing, not counting the data fetch takes maybe 40 to 45 us ...

the C++ JNI data fetch time of 30 us is not lightning fast, but something i have to live with ... 30 us * 500 * 6 = 90 ms for the whole data fetch only portion ... i could do this 10 times / sec if the redraw wouldn't take any time

i use the FastLineAndPointRenderer.Formatter setup

```<code>public static FastLineAndPointRenderer.Formatter LineFormat (int color, int width, int dash, int spc)
{
  Paint paint = new Paint () ;
  paint.setColor (color) ;
  paint.setStyle (Paint.Style.STROKE) ;
  paint.setAntiAlias (false) ;
  paint.setStrokeWidth (PixelUtils.dpToPix (width)) ;
  paint.setPathEffect (new DashPathEffect (
                       new float [] { PixelUtils.dpToPix (dash), PixelUtils.dpToPix (spc) }, 0)) ;

  FastLineAndPointRenderer.Formatter line = new FastLineAndPointRenderer.Formatter (paint.getColor (), null, null) ;
  line.setLinePaint     (paint) ;
  line.setVertexPaint       (null) ;
  line.setPointLabelFormatter (null) ;

  return line ;
}
</code>```

please, can anyone shine a bit more light onto my setup and comment this paper

is there a way to speed it up and still sick with 500 x-points ... that's what's being used in QT on the desktop setup and it's zippy zippy fast

what can be improved and what additional info should i provide

i hope i do not have made too many typos ;)

答:
As far as the scroll characteristics go, I don't have an in depth answer there but I imagine there's some sort of message loop / throttling occurring inside the OS.  Have you measured the scroll callback without the redraw call to get a sense of what the max theoretical frequency of the scroll cb is?

In any case, speeding up your render times can only help so here are a couple general suggestions:

Probably the biggest thing you can do to boost performance in your app is to use FastXYSeries.  This means either using your own or using SampledXYSeries which is the only "out of the box" implementation.  My suggestion would be to implement your own.

To get the best results from this approach you'll also need to set a min/max y boundary and make sure that your series min/max y-vals all fall within that boundary.  The idea is that for apps that draw a stream of incoming data, it's possible to maintain a running tally of the min/max values observed.  The FastXYSeries interface gives Androidplot a way to query these values allowing it skip the very expensive step of iterating through each series looking for visible min/max vals.

If FastXYSeries is not feasible, then using just about any optimized XYSeries implementation besides SimpleXYSeries will be an improvement as it is optimized for versatility, not performance.  For dynamic plots of a fixed size (as yours appears to be) FixedSizeEditableXYSeries is a particularly good choice.

EDIT: Updates to added questions below

all the above so far has been done using the
  FastLineAndPointRenderer.Formatter which doesn't seem to care if the
  setInterpolationParams is being used ... would make sense since we
  want to do it fast

Correct (noted in the class Javadoc)

one wonders about the differences between the LineAndPointFormatter
  and the FastLineAndPointRenderer.Formatter since this setup provides
  the same timing

There are several differences but the two main ones are:
 * Bare minimum number of instantiations of new instances on each render cycle.
 * Draws each series using simple line segments instead of a Path.

It's definitely much faster.  If you're not seeing a difference in your benchmarks I'd have to assume that either the benchmark is not accurate or theres a bottleneck elsewhere in your render cycle.  One thing you can try is using Androidplot's PlotStatistics utility.  The DemoApp's orientation sensor sample provides a usage example.  It provides an actual performance and theoretical performance (performance of Androidplot's internal rendering only) value in FPS overlay on the plot for which it is enabled.  If the two numbers are vastly different then it means the bottleneck is outside of Androidplot.  The most common source of bottlenecks is not usin separate threads thread to monitor your sample source and trigger redraws to your plot at a stable frequency.  The ECG plot in the DemoApp provides a reasonable example of doing this.

I also noticed in your code above that you do quite a bit of logging. Keep in mind that logging is very expensive and can have a significant impact on performance, particularly if you are calling it on every invocation of getY() as it appears above.  I would not be at all surprised if the overhead is upwards of 10-30% here.

Body:
i did evaluate the run-time performance of a 6 XYSeries plot setup (500 X axis samples) on a nexus 7 2013 with simple synthesized sine waves in the getY (idx) functs and compared it to a JNI getY (idx) based setup where the JNI C++ code simply fetched the data from a buffer within the JNI capsule

here is a simplified setup for the synthesized sine wave generation (example shows one XYSeries)

public static int  DatCnt = 0 ;
       static long DatSav ;

@Override
public double GetY (int idx) // being called by super.getY (idx), which implements XYSeries
{
  long t0 = 0 ;

  if (DatCnt >    0) { DatCnt-- ; t0 = System.nanoTime () ; }
  if (DatCnt == 499)   DatSav   = t0 ;

  double dat = Sin (idx) * 45 + 50 ;

//if (DatCnt >    0 &&
//    DatCnt <   10) {
//  Log.i ("com.efiLabs.PlotXYtst", String.format ("dat0 %6d %d", (System.nanoTime () - t0) / 1000, DatCnt)) ;
//}
  if (DatCnt ==   1) {                                                                   ActPlotNew0.Tsum += t0 - DatSav ;
    Log.i ("com.efiLabs.PlotXYtst", String.format ("dat0 %6d %6d", (t0 - DatSav) / 1000, ActPlotNew0.Tsum / 1000)) ;
  }
  return dat ;
//return Sin (idx) * 45 + 50 ;
}

and this is the android monitor output

06-04 16:14:40.707 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onDown x_1493 y_523
06-04 16:14:40.797 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_23
06-04 16:14:40.797 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 233989457389
06-04 16:14:40.861 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat0  33874  33874
06-04 16:14:40.901 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat1  26428  60302
06-04 16:14:40.938 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat2  24627  84930
06-04 16:14:40.974 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat3  25299 110229
06-04 16:14:41.010 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat4  24047 134277
06-04 16:14:41.046 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat5  25299 159576
06-04 16:14:41.069 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_517
06-04 16:14:41.069 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 272247
06-04 16:14:41.129 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat0  24322  24322
06-04 16:14:41.165 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat1  24536  48858
06-04 16:14:41.200 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat2  24688  73547
06-04 16:14:41.236 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat3  24414  97961
06-04 16:14:41.271 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat4  23895 121856
06-04 16:14:41.305 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat5  23834 145690
06-04 16:14:41.326 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_37
06-04 16:14:41.326 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 256622
06-04 16:14:41.387 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat0  23834  23834
06-04 16:14:41.429 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat1  30395  54229
06-04 16:14:41.473 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat2  28411  82641
06-04 16:14:41.507 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat3  23406 106048
06-04 16:14:41.542 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat4  23803 129852
06-04 16:14:41.576 18061-18061/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: dat5  24108 153961

a vertical scroll will start the loop with the DatUpd () functs being called periodically

public static long Tstart, Tsum ;

public synchronized void DataUpd ()
{

  LogI (String.format ("sum %d", (System.nanoTime () - Tstart) / 1000)) ;

  DataY_0.DatCnt = 500 ;
  DataY_1.DatCnt = 500 ;
  DataY_2.DatCnt = 500 ;
  DataY_3.DatCnt = 500 ;
  DataY_4.DatCnt = 500 ;
  DataY_5.DatCnt = 500 ;

  Tstart = System.nanoTime () ;
  Tsum   = 0 ;

  Plot.redraw () ;
}

the "dat3 25299 110229" shows the exex times for each series (dat0 - dat5), whereas the 1st number is the individual time accumulation from the x-data 0 to 500, and the 2nd is a running time tally ... 25299 us for the dat3 series and 110299 us for dat0 to dat3 and so on ... an average data fetch time per ZYSeries is about 25 ms

the total sum of 272247 us is the time from the 1st DatUpd () call to the next one in the scroll operation ... i didn't have a hook into when the plot redraw process was complete

the total getY (idx) data fetch time for all 6 XYSeries is 159576 us and the total redraw cycle time 272247 us ... 272247 - 159576 = 112671 us

of course i do not have any idea of the percentage of the remaining time (after the fetch time) of 112671 us, which is androidplot time and which is scroll gesture processing

and now to the C++ JNI setup timing

06-04 17:09:39.783 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onDown x_1620 y_497
06-04 17:09:39.881 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_16
06-04 17:09:39.882 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 25543273
06-04 17:09:39.947 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rdif  36865  36865
06-04 17:09:39.995 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rpm   36956  73822
06-04 17:09:40.032 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: tdif  36224 110046
06-04 17:09:40.085 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext0  42205 152252
06-04 17:09:40.138 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext1  41778 194030
06-04 17:09:40.202 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: raw2  53955 247985
06-04 17:09:40.226 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_724
06-04 17:09:40.226 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 344085
06-04 17:09:40.293 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rdif  36956  36956
06-04 17:09:40.341 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rpm   36651  73608
06-04 17:09:40.377 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: tdif  36315 109924
06-04 17:09:40.429 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext0  40954 150878
06-04 17:09:40.481 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext1  40802 191680
06-04 17:09:40.534 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: raw2  41015 232696
06-04 17:09:40.555 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: onScroll x_4
06-04 17:09:40.555 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: sum 329620
06-04 17:09:40.619 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rdif  36712  36712
06-04 17:09:40.666 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: rpm   36499  73211
06-04 17:09:40.702 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: tdif  36163 109375
06-04 17:09:40.779 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext0  63323 172698
06-04 17:09:40.836 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: ext1  42266 214965
06-04 17:09:40.888 4067-4067/com.efiLabs.PlotXY2tst I/com.efiLabs.PlotXYtst: raw2  41259 256225

comparison :

accumulated fetch time is 247985 us

the sine synthesized data fetches take an average 25 ms / series whereas the C++ JNI data fetches take about 40 ms ... 15 ms longer, an increase of 60 % over the sine wave synthesis example

the percentage of the getY (idx) synthesized sine wave generation time portion is unknown and so is what else is happening inside androidplot from one getY (idx) to the next one

25 ms / 500 x-samples is 50 us, 15 ms / 500 x-samples = 30 us   ... assuming that the sine calculation can't take the majority of the 50 us i would say that a single getY (idx) call processing, not counting the data fetch takes maybe 40 to 45 us ...

the C++ JNI data fetch time of 30 us is not lightning fast, but something i have to live with ... 30 us * 500 * 6 = 90 ms for the whole data fetch only portion ... i could do this 10 times / sec if the redraw wouldn't take any time

i use the FastLineAndPointRenderer.Formatter setup

public static FastLineAndPointRenderer.Formatter LineFormat (int color, int width, int dash, int spc)
{
  Paint paint = new Paint () ;
  paint.setColor (color) ;
  paint.setStyle (Paint.Style.STROKE) ;
  paint.setAntiAlias (false) ;
  paint.setStrokeWidth (PixelUtils.dpToPix (width)) ;
  paint.setPathEffect (new DashPathEffect (
                       new float [] { PixelUtils.dpToPix (dash), PixelUtils.dpToPix (spc) }, 0)) ;

  FastLineAndPointRenderer.Formatter line = new FastLineAndPointRenderer.Formatter (paint.getColor (), null, null) ;
  line.setLinePaint     (paint) ;
  line.setVertexPaint       (null) ;
  line.setPointLabelFormatter (null) ;

  return line ;
}

please, can anyone shine a bit more light onto my setup and comment this paper

is there a way to speed it up and still sick with 500 x-points ... that's what's being used in QT on the desktop setup and it's zippy zippy fast

what can be improved and what additional info should i provide

i hope i do not have made too many typos ;)


答:
I would suggest defining a variable</p>

```<code> var roundedX = Math.Round(X);
 for (int i = 0; i < roundedX; i++)
 {
    //Some code
 }
</code>```

Title: Is using a math class method in a loop condition slow?

Body:
I would suggest defining a variable

 var roundedX = Math.Round(X);
 for (int i = 0; i < roundedX; i++)
 {
    //Some code
 }


问:
Finding mac Address using IP address in java
```<code>public static void main(String[] args) {
    try {
        InetAddress address = InetAddress.getLocalHost();
        // InetAddress address = InetAddress.getByName("192.168.46.53");

        /*
         * Get NetworkInterface for the current host and then read the
         * hardware address.
         */
        NetworkInterface ni = NetworkInterface.getByInetAddress(address);
        if (ni != null) {
            byte[] mac = ni.getHardwareAddress();
            if (mac != null) {
                /*
                 * Extract each array of mac address and convert it to hexa with the
                 * following format 08-00-27-DC-4A-9E.
                 */
                for (int i = 0; i < mac.length; i++) {
                    System.out.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "");
                }
            } else {
                System.out.println("Address doesn't exist or is not accessible.");
            }
        } else {
            System.out.println("Network Interface for the specified address is not found.");
        }
</code>```

I'm having a problem finding the MAC address of a remote host, but I am able to find the MAC address of my local host. If I have the IP address of the other system can I retrieve the MAC address of that system?

InetAddress address = InetAddress.getByName("192.168.46.53");

if i specify the ip address of a system in my workgroup... ni values gets null.... and not able to fetch it.... but if give my ip address of my system...it fetches???

Thanks,

Sunny

答:
You will only be able to fetch the MAC address of remote hosts on your local LAN, that is, hosts that are in the same subnet as your computer.  MAC addresses of hosts more than one hop away (IP hop, not Ethernet hop) cannot be determined.

And note that fetching the corresponding MAC address for hosts on your local LAN requires the permissions necessary to fetch either the ARP table, or those necessary to send and receive raw packets.  Most OSes allow reading of the ARP table without special permissions, but the mechanism you use to do so will change depending on the OS.  If you need a technique for a particular OS, you will have to update your question to include that info.

Body:
public static void main(String[] args) {
    try {
        InetAddress address = InetAddress.getLocalHost();
        // InetAddress address = InetAddress.getByName("192.168.46.53");

        /*
         * Get NetworkInterface for the current host and then read the
         * hardware address.
         */
        NetworkInterface ni = NetworkInterface.getByInetAddress(address);
        if (ni != null) {
            byte[] mac = ni.getHardwareAddress();
            if (mac != null) {
                /*
                 * Extract each array of mac address and convert it to hexa with the
                 * following format 08-00-27-DC-4A-9E.
                 */
                for (int i = 0; i < mac.length; i++) {
                    System.out.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "");
                }
            } else {
                System.out.println("Address doesn't exist or is not accessible.");
            }
        } else {
            System.out.println("Network Interface for the specified address is not found.");
        }

I'm having a problem finding the MAC address of a remote host, but I am able to find the MAC address of my local host. If I have the IP address of the other system can I retrieve the MAC address of that system?

InetAddress address = InetAddress.getByName("192.168.46.53");

if i specify the ip address of a system in my workgroup... ni values gets null.... and not able to fetch it.... but if give my ip address of my system...it fetches???

Thanks,

Sunny


问:
What happens if a thread re-assigns a variable in java?
I want to know if the following (contrived) example is thread safe:

```<code>public class SpringSingleton
{

    private MyObject _myObject = new MyObject("hello");

    public void useObject()
    {
        _myObject.doSomethingCool();
    }

    public void changeObject()
    {
        _myObject = new MyObject("goodbye");
    }

    public static void main(String[] args)
    {
        // Have multiple threads, some using and some changing the object
    }

}
</code>```

My main question is: what will happen when one thread tries to call useObject() at the same time another thread tries to call changeObject()?

答:
Assigning a reference is an atomic operation. You can never see a half-assigned reference. So the thread calling the doSomethingCool() method will either call it on the old reference, or on the new one.

But that doesn't make the code thread-safe. You can also have visibility problems: the thread reading the reference might see an old one even though  the thread has already written a new reference. To solve that problem, you need to make the field volatile, or to wrap it into an AtomicReference, or to synchronize all accesses to the field.

Also note that if you ever change the code to

```<code>_myObject.doSomethingCool();
_myObject.doSomethingElse();
</code>```

then you'll have another problem: the first call might be done on the old object, and the second on the new one. If coherence is necessary between these two calls, then those two calls, as well as every other interaction with _myObject, should be wrapped into a synchronized block (using the same lock).

Body:
I want to know if the following (contrived) example is thread safe:

public class SpringSingleton
{

    private MyObject _myObject = new MyObject("hello");

    public void useObject()
    {
        _myObject.doSomethingCool();
    }

    public void changeObject()
    {
        _myObject = new MyObject("goodbye");
    }

    public static void main(String[] args)
    {
        // Have multiple threads, some using and some changing the object
    }

}

My main question is: what will happen when one thread tries to call useObject() at the same time another thread tries to call changeObject()?

Body:
Assigning a reference is an atomic operation. You can never see a half-assigned reference. So the thread calling the doSomethingCool() method will either call it on the old reference, or on the new one.

But that doesn't make the code thread-safe. You can also have visibility problems: the thread reading the reference might see an old one even though  the thread has already written a new reference. To solve that problem, you need to make the field volatile, or to wrap it into an AtomicReference, or to synchronize all accesses to the field.

Also note that if you ever change the code to

_myObject.doSomethingCool();
_myObject.doSomethingElse();

then you'll have another problem: the first call might be done on the old object, and the second on the new one. If coherence is necessary between these two calls, then those two calls, as well as every other interaction with _myObject, should be wrapped into a synchronized block (using the same lock).