问:
Display user profile url by name instead of ID
I am Newbie. I'm trying to return a view of member profile

At the moment, the user profile is accessible by its ID, like so

profile/7

I would like to access it through the name that I've created

profile/John

this is my route

```<code>Route::get('profile/{id}', 'ProfilController@tampilkanID');
</code>```

this is my controller

```<code>public function tampilkanID($id)
{
    $auth = Auth::user()->id;
    $users=\App\users::all()->whereNotIn('id',$auth);
    $tampilkan = Users::find($id);
    return view('tampilkan', compact('tampilkan', 'users'));
}
</code>```

and this how i call it in my blade

```<code> @foreach($users as $user)
           <tr>
               <td><a id="teamname" href="{{ url('profile',$user->id) }}" target="_blank">{{$user->name}}</a></td>
              </tr>
 @endforeach
</code>```

thank you

答:
You can use laravel Route Model Binding.

What is Route Model Binging?

Route model binding in Laravel provides a mechanism to inject a model instance into your routes.

How can I use it?

Pass object rather then id like

```<code>Route::get('users/{user}', function ($user) {
    return view('user.show', compact('user'));
});
</code>```

In your User.php define getRouteKeyName then return whatever you want as a route

```<code>public function getRouteKeyName()
{
    return 'name'; //this will return user name as route
}
</code>```

so your route will be users/name

For more information have a look at laravel documentation https://laravel.com/docs/5.5/routing#route-model-binding

Body:
I am Newbie. I'm trying to return a view of member profile

At the moment, the user profile is accessible by its ID, like so

profile/7

I would like to access it through the name that I've created

profile/John

this is my route

Route::get('profile/{id}', 'ProfilController@tampilkanID');

this is my controller

public function tampilkanID($id)
{
    $auth = Auth::user()->id;
    $users=\App\users::all()->whereNotIn('id',$auth);
    $tampilkan = Users::find($id);
    return view('tampilkan', compact('tampilkan', 'users'));
}

and this how i call it in my blade

 @foreach($users as $user)

               id) }}" target="_blank">{{$user->name}}

 @endforeach

thank you

Body:
You can use laravel Route Model Binding.

What is Route Model Binging?

Route model binding in Laravel provides a mechanism to inject a model instance into your routes.

How can I use it?

Pass object rather then id like

Route::get('users/{user}', function ($user) {
    return view('user.show', compact('user'));
});

In your User.php define getRouteKeyName then return whatever you want as a route

public function getRouteKeyName()
{
    return 'name'; //this will return user name as route
}

so your route will be users/name

For more information have a look at laravel documentation https://laravel.com/docs/5.5/routing#route-model-binding


来源: stackexchange

问:
How to rotate a large background image once the next image loads, but without having to preload all at once?
I need a large rotating background image on a homepage. This is how I want it to work:

During the first round, the next image is displayed only after it is preloaded. While it's waiting on the current image, there should be a small spinner overlaid in the corner. Once it cycles through each and consequently they all have been loaded, it will default to a regular interval.

I don't want to have to preload all the images and then cycle through, but I also don't want to just cycle through and have one disappear and a gap until the next loads.

I've been looking around for jQuery plugins that cycle background images and preload only the next image at a time. So far I've just found plugins that only rotate or only preload. Does what I want exist? If so, where can I find it? Otherwise, do I have to find a way to merge the two myself? Any tips for doing that?

Thanks for any help!

答:
Maybe this will help you out:

Advanced jQuery background image slideshow

Good luck, please tell me if that was what you were looking for!

ContentLicense: CC BY-SA 2.5


问:
Java - String value is getting break when doing a concat

I am preparing a mail content using HTML (I am using spring mime message for sending mails) with embedded images in it. The HTML is as follow.

```<code><html><body><div><div style='margin-top: 0; margin-bottom: 0;'><font face='Times New Roman' size='3'> </font></div><div style='margin-top: 0; margin-bottom: 0;'><table width='100%' style='border-collapse: collapse; width: 100%;'><tbody><tr height='8' style='height: 8px;'><td style='width: 100%; padding: 0; border: 0 none black;'><table width='100%'style='border-collapse: collapse; width: 100%;'><tbody><tr height='8' style='height: 8px;'><td style='width: 100%; padding: 0; border: 0 none black;'><table width='600' align='center' style='border-collapse: collapse; width: 600px;><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border: 0 none black;'><table width='600' align='center'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600'style='width: 600px; padding: 0; border: 0 none black;'><table width='600' align='left'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0;border: 0 none black;'><table width='600' align='left'style='border-collapse:collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600'style='width:600px; padding:0; border: 0 none black;'><div align='center' style='text-align:center;'><a href='http://www.e-XXXXbank.com/'target='_blank'> <img src='cid:logo' 'align='top' alt='logo' style='display:inline;'></a></div></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center'<tbody><tr height='8' style='height: 8px;'><td width='600'style='width: 600px; padding: 0; border: 0 none black;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='560'style='width: 560px; padding: 0; border: 0 none black;'><table width='100%'style='border-collapse: collapse; width: 100%;'><tbody><tr height='8' style='height: 8px;'><td style='width: 100%; padding: 0; border: 0 none black;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='558'style='width: 558px; background-color: #F0F0F0; padding: 0; border: 1px solid #ECECED;'><span style='background-color: #F0F0F0;'><div align='center' style='text-align: center;'><font face='Arial' size='4' color='#104160'><b>XXXX Portfolio Confirmation</b></font></div></span></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border: 0 none black;'><img src='cid:space' align='top'alt='space' style='display: inline;'></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600'style='width: 600px; padding: 0; border: 0 none black;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='560'style='width: 560px; padding: 0; border: 0 none black;'><table width='550' align='right'style='border-collapse: collapse; width: 550px;'><tbody><tr height='8' style='height: 8px;'><td width='550'style='width: 550px; padding: 0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td width='550'style='width: 550px; padding: 0; border: 0 none black;'><table width='550' align='left'style='border-collapse: collapse; width: 550px;'><tbody><tr height='8' style='height: 8px;'><td colspan='2' width='550'style='width: 550px; padding: 0; border: 0 none black;'><font face='Arial' size='4' color='#C21212'><b>Dear Customer</b></font></td></tr><tr height='8' style='height: 8px;'><td colspan='2' width='550'style='width: 550px; padding: 0; border: 0 none black;'><font face='Arial' size='4' color='#104160'><br>Following your instructions we have created your XXXX. The document attached enable you to view the details of your portfolio. You can save, print and store it for your records.</font><font face='Arial' size='4' color='#104160'><br></font><font face='Arial' size='4' color='#104160'><br>For security reasons, the document is protected with a password that has been sent to your mobile by SMS.</font><font face='Arial' size='4' color='#104160'><br></font><font face='Arial' size='4' color='#104160'><br>Many thanks for trusting us to help you manage your finances.</font></td></tr><tr height='8' style='height: 8px;'><td width='510' style='width: 510px; padding: 0; border: 0 none black;'></td><td width='39' style='width: 39px; padding: 0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td colspan='2' width='550'style='width: 550px; padding: 0; border: 0 noneblack;'><font face='Arial' size='4' color='#C21212'><b>XXXX YYYYY Customer Service</b></font></td></tr><tr height='8' style='height: 8px;'><td width='510' valign='top'style='width: 510px; padding: 0; border: 0 none black;'><table width='510' align='left'style='border-collapse: collapse; width:510px;'><tbody><tr height='8' style='height: 8px;'><td width='510'style='width: 510px; padding:0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td width='510'style='width: 510px; padding:0; border: 0 none black;'><font face='Times New Roman' size='2'> </font> <div style='margin-top: 0;margin-bottom: 0;'><font face='Times New Roman' size='2'> </font></div><div style='margin-top: 0;margin-bottom: 0;'><font face='Times New Roman' size='2'> </font></div><div style='margin-top: 0;margin-bottom: 0;'><font face='Times New Roman' size='2'> </font></div><div style='margin-top: 0;margin-bottom: 0;'><font face='Arial' size='2'color='#104160'>Please add </font><a href='mailto:XXXXYYYYY@XXXXbank.com.kw'target='_blank'><font face='Arial'size='2'>XXXXYYYYY@XXXXbank.com.kw</font></a><font face='Arial' size='2'color='#104160'> to your email address book to ensure your statements are not redirected to the junk folder.If there are any questions, please contact directly with your XXXX Bank manager.</font></div></td></tr><tr height='8' style='height: 8px;'><td width='510' style='width: 510px; padding: 0; border: 0 none black;'></td></tr></tbody></table></td><td width='39' style='width: 39px; padding: 0; border: 0 none black;'></td></tr></tbody></table> </td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table> </td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center' style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border-width: 0 0 1px 0; border-style: none none solid none; border-color: black;'></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><table width='600' align='center' style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border: 0 none black;'></td></tr></tbody></table> <br></td></tr><tr height='8' style='height: 8px;'><td style='background-color: #F0F0F0; padding: 0; border: 0 none black;'><span style='background-color: #F0F0F0;'><table width='600' align='center' style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border-width: 1px 0 0 0; border-style: solid none none none; border-color: #E6E6E6;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='560' style='width: 560px; padding: 0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td width='560' style='width: 560px; padding: 0; border: 0 none black;'><table width='500' align='center' style='border-collapse: collapse; width: 500px;'><tbody><tr height='8' style='height: 8px;'><td width='300' style='width: 300px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><font face='Arial' size='2' color='#C21212'>© 2016 XXXX Bank. All rights reserved. </font><font face='Arial' size='2' color='#004080'>                    </font></div></td><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='https://XXX/XXXX?_rdr' target='_blank'><img src='cid:facebook' alt='facebook' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='http://XXXX.com/XXXX' target='_blank'><img src='cid:twitter' align='top' alt='twitter' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='http://XXXXX.com/XXXX' target='_blank'><img src='cid:Instagram' align='top'alt='Instagram' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='https://www.youtube.com/XXX/YYYY' target='_blank'><img src='cid:youtube' align='top' alt='youtube' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='https://www.linkedin.com/company/XXXX?trk=hb_tab_compy_id_202412' target='_blank'><img src='cid:linkedIn' align='top' alt='linkedIn' style='display:inline;'></a></div></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td width='560'style='width: 560px; padding: 0; border: 0 none black;'></td></tr></tbody></table> </td></tr></tbody></table></span></td</tr></tbody></table></div><div style='margin-top: 0; margin-bottom: 0;'><font face='Times New Roman' size='3'> </font></div><div style='margin-top: 0; margin-bottom: 0;'><img src='cid:tree' alt='http://XXXX/tree-small.jpg' style='display:inline;'><font face='Arial' size='1' color='green'>Please consider theenvironment & Print only if necessary</font></div><hr></div></body></html>
</code>```

I have prepared the mail content using string and embedded the images using CID

```<code>String htmltext1=mailContentStart.concat(mailContentLogo).concat(mailContentHeading).
                concat(mailContentSpace).concat(mailContentBody);
        String htmltext12=(mailContentImages).concat(mailEnd);
</code>```

When I contact htmltext 1 and htmltext2 am ending up with the below results

```<code><html><body><div><div style='margin-top: 0; margin-bottom: 0;'><font face='Times New Roman' size='3'> </font></div><div style='margin-top: 0; margin-bottom: 0;'><table width='100%' style='border-collapse: collapse; width: 100%;'><tbody><tr height='8' style='height: 8px;'><td style='width: 100%; padding: 0; border: 0 none black;'><table width='100%'style='border-collapse: collapse; width: 100%;'><tbody><tr height='8' style='height: 8px;'><td style='width: 100%; padding: 0; border: 0 none black;'><table width='600' align='center' style='border-collapse: collapse; width: 600px;><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border: 0 none black;'><table width='600' align='center'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600'style='width: 600px; padding: 0; border: 0 none black;'><table width='600' align='left'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0;border: 0 none black;'><table width='600' align='left'style='border-collapse:collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600'style='width:600px; padding:0; border: 0 none black;'><div align='center' style='text-align:center;'><a href='http://www.e-XXXXbank.com/'target='_blank'> <img src='cid:logo' 'align='top' alt='logo' style='display:inline;'></a></div></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center'<tbody><tr height='8' style='height: 8px;'><td width='600'style='width: 600px; padding: 0; border: 0 none black;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='560'style='width: 560px; padding: 0; border: 0 none black;'><table width='100%'style='border-collapse: collapse; width: 100%;'><tbody><tr height='8' style='height: 8px;'><td style='width: 100%; padding: 0; border: 0 none black;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='558'style='width: 558px; background-color: #F0F0F0; padding: 0; border: 1px solid #ECECED;'><span style='background-color: #F0F0F0;'><div align='center' style='text-align: center;'><font face='Arial' size='4' color='#104160'><b>XXXX Portfolio Confirmation</b></font></div></span></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border: 0 none black;'><img src='cid:space' align='top'alt='space' style='display: inline;'></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center'style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600'style='width: 600px; padding: 0; border: 0 none black;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='560'style='width: 560px; padding: 0; border: 0 none black;'><table width='550' align='right'style='border-collapse: collapse; width: 550px;'><tbody><tr height='8' style='height: 8px;'><td width='550'style='width: 550px; padding: 0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td width='550'style='width: 550px; padding: 0; border: 0 none black;'><table width='550' align='left'style='border-collapse: collapse; width: 550px;'><tbody><tr height='8' style='height: 8px;'><td colspan='2' width='550'style='width: 550px; padding: 0; border: 0 none black;'><font face='Arial' size='4' color='#C21212'><b>Dear Customer</b></font></td></tr><tr height='8' style='height: 8px;'><td colspan='2' width='550'style='width: 550px; padding: 0; border: 0 none black;'><font face='Arial' size='4' color='#104160'><br>Following your instructions we have created your XXXX. The document attached enable you to view the details of your portfolio. You can save, print and store it for your records.</font><font face='Arial' size='4' color='#104160'><br></font><font face='Arial' size='4' color='#104160'><br>For security reasons, the document is protected with a password that has been sent to your mobile by SMS.</font><font face='Arial' size='4' color='#104160'><br></font><font face='Arial' size='4' color='#104160'><br>Many thanks for trusting us to help you manage your finances.</font></td></tr><tr height='8' style='height: 8px;'><td width='510' style='width: 510px; padding: 0; border: 0 none black;'></td><td width='39' style='width: 39px; padding: 0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td colspan='2' width='550'style='width: 550px; padding: 0; border: 0 noneblack;'><font face='Arial' size='4' color='#C21212'><b>XXXX YYYYY Customer Service</b></font></td></tr><tr height='8' style='height: 8px;'><td width='510' valign='top'style='width: 510px; padding: 0; border: 0 none black;'><table width='510' align='left'style='border-collapse: collapse; width:510px;'><tbody><tr height='8' style='height: 8px;'><td width='510'style='width: 510px; padding:0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td width='510'style='width: 510px; padding:0; border: 0 none black;'><font face='Times New Roman' size='2'> </font> <div style='margin-top: 0;margin-bottom: 0;'><font face='Times New Roman' size='2'> </font></div><div style='margin-top: 0;margin-bottom: 0;'><font face='Times New Roman' size='2'> </font></div><div style='margin-top: 0;margin-bottom: 0;'><font face='Times New Roman' size='2'> </font></div><div style='margin-top: 0;margin-bottom: 0;'><font face='Arial' size='2'color='#104160'>Please add </font><a href='mailto:XXXXYYYYY@XXXXbank.com.kw'target='_blank'><font face='Arial'size='2'>XXXXYYYYY@XXXXbank.com.kw</font></a><font face='Arial' size='2'color='#104160'> to your email address book to ensure your statements are not redirected to the junk folder.If there are any questions, please contact directly with your XXXX Bank manager.</font></div></td></tr><tr height='8' style='height: 8px;'><td width='510' style='width: 510px; padding: 0; border: 0 none black;'></td></tr></tbody></table></td><td width='39' style='width: 39px; padding: 0; border: 0 none black;'></td></tr></tbody></table> </td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table> </td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><br><table width='600' align='center' style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border-width: 0 0 1px 0; border-style: none none solid none; border-color: black;'></td></tr></tbody></table></td></tr><tr height='8' style='height: 8px;'><td style='padding: 0; border: 0 none black;'><table width='600' align='center' style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border: 0 none black;'></td></tr></tbody></table> <br></td></tr><tr height='8' style='height: 8px;'><td style='background-color: #F0F0F0; padding: 0; border: 0 none black;'><span style='background-color: #F0F0F0;'><table width='600' align='center' style='border-collapse: collapse; width: 600px;'><tbody><tr height='8' style='height: 8px;'><td width='600' style='width: 600px; padding: 0; border-width: 1px 0 0 0; border-style: solid none none none; border-color: #E6E6E6;'><table width='560' align='center'style='border-collapse: collapse; width: 560px;'><tbody><tr height='8' style='height: 8px;'><td width='560' style='width: 560px; padding: 0; border: 0 none black;'></td></tr><tr height='8' style='height: 8px;'><td width='560' style='width: 560px; padding: 0; border: 0 none black;'><table width='500' align='center' style='border-collapse: collapse; width: 500px;'><tbody><tr height='8' style='height: 8px;'><td width='300' style='width: 300px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><font face='Arial' size='2' color='#C21212'>© 2016 XXXX Bank. All rights reserved. </font><font face='Arial' size='2' color='#004080'>                    </font></div></td><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='https://XXX/XXXX?_rdr' target='_blank'><img src='cid:facebook' alt='facebook' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='http://XXXX.com/XXXX' target='_blank'><img src='cid:twitter' align='top' alt='twitter' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='http://XXXXX.com/XXXX' target='_blank'><img src='cid:Instagram' align='top'alt='Instagram' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='https://www.youtube.com/XXX/YYYY' target='_blank'><img src='cid:youtube' align='top' alt='youtube' style='display:inline;'></a><td width='30' style='width: 30px; padding: 0; border: 0 none black;'><div align='center' style='text-align: center;'><a href='htt.....
</code>```

Can anyone suggest to resolve the same. Because of this my HTML is not getting rendered properly in MAIL.

答:
I would recommend you using the StringBuilder here instead of the concat.
Or if not that, simple use + operator here instead of concat.

The concat() method only accepts String values while the + operator will silently convert the argument to a String (using the toString() method for objects). So the concat() method is more strict in what it accepts.

To use the StringBuilder you can replace the above two lines in your code with this snippet:

```<code>StringBuilder html = new StringBuilder();
html.append(mailContentStart)
        .append(mailContentLogo)
        .append(mailContentHeading)
        .append(mailContentSpace)
        .append(mailContentBody)
        .append(mailContentImages)
        .append(mailEnd);
</code>```

And you can return the String value of this StringBuilder by doing this:

```<code>return html.toString();
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am preparing a mail content using HTML (I am using spring mime message for sending mails) with embedded images in it. The HTML is as follow.

<table width='600' align='center'

XXXX Portfolio Confirmation

Dear Customer

Following your instructions we have created your XXXX. The document attached enable you to view the details of your portfolio. You can save, print and store it for your records.

For security reasons, the document is protected with a password that has been sent to your mobile by SMS.

Many thanks for trusting us to help you manage your finances.

XXXX YYYYY Customer Service

Please add XXXXYYYYY@XXXXbank.com.kw to your email address book to ensure your statements are not redirected to the junk folder.If there are any questions, please contact directly with your XXXX Bank manager.

© 2016 XXXX Bank. All rights reserved.

</td

Please consider theenvironment & Print only if necessary

I have prepared the mail content using string and embedded the images using CID

String htmltext1=mailContentStart.concat(mailContentLogo).concat(mailContentHeading).
                concat(mailContentSpace).concat(mailContentBody);
        String htmltext12=(mailContentImages).concat(mailEnd);

When I contact htmltext 1 and htmltext2 am ending up with the below results

<table width='600' align='center'

XXXX Portfolio Confirmation

Dear Customer

Following your instructions we have created your XXXX. The document attached enable you to view the details of your portfolio. You can save, print and store it for your records.

For security reasons, the document is protected with a password that has been sent to your mobile by SMS.

Many thanks for trusting us to help you manage your finances.

XXXX YYYYY Customer Service

Please add XXXXYYYYY@XXXXbank.com.kw to your email address book to ensure your statements are not redirected to the junk folder.If there are any questions, please contact directly with your XXXX Bank manager.

© 2016 XXXX Bank. All rights reserved.

<a href='htt.....

Can anyone suggest to resolve the same. Because of this my HTML is not getting rendered properly in MAIL.

Body:
I would recommend you using the StringBuilder here instead of the concat.
Or if not that, simple use + operator here instead of concat.

The concat() method only accepts String values while the + operator will silently convert the argument to a String (using the toString() method for objects). So the concat() method is more strict in what it accepts.

To use the StringBuilder you can replace the above two lines in your code with this snippet:

StringBuilder html = new StringBuilder();
html.append(mailContentStart)
        .append(mailContentLogo)
        .append(mailContentHeading)
        .append(mailContentSpace)
        .append(mailContentBody)
        .append(mailContentImages)
        .append(mailEnd);

And you can return the String value of this StringBuilder by doing this:

return html.toString();


问:
dynamically include a layout to another layout file inside a fragment
I have a fragment layout to which i want to add another sub layout dynamically ,

I tried this https://stackoverflow.com/a/22592269/8476022

sub-layout xml

```<code><?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:hint="Question"
    android:textColor="@color/colorTextBlack"
    android:textSize="16dp" />
</android.support.constraint.ConstraintLayout>
</code>```

this is my main layout

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f2f2f2"
android:orientation="vertical">
<FrameLayout
    android:id="@+id/flContainer"
    android:layout_width="match_parent"
    android:layout_margin="20dp"
    android:layout_height="wrap_content"/>
</LinearLayout>
</code>```

inside my fragment i included the sublayout

```<code>@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_start_question, container, false);
     flContainer = (FrameLayout) v.findViewById(R.id.flContainer);
     flContainer.addView(R.layout.sub_layout);
    return v;
}
</code>```

but i am getting error near addView the screenshot is below

can anyone please help to find the error

答:
Replace your onCreateView with the following,    </p>

```<code>@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_start_question, container, false);
    flContainer = (FrameLayout) v.findViewById(R.id.flContainer);
    View subView = inflater.inflate(R.layout.sub_layout, null);
    flContainer.addView(subView);
    return v;
}
</code>```

Body:
I have a fragment layout to which i want to add another sub layout dynamically ,

I tried this https://stackoverflow.com/a/22592269/8476022

sub-layout xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:hint="Question"
    android:textColor="@color/colorTextBlack"
    android:textSize="16dp" />
</android.support.constraint.ConstraintLayout>

this is my main layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f2f2f2"
android:orientation="vertical">
<FrameLayout
    android:id="@+id/flContainer"
    android:layout_width="match_parent"
    android:layout_margin="20dp"
    android:layout_height="wrap_content"/>
</LinearLayout>

inside my fragment i included the sublayout

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_start_question, container, false);
     flContainer = (FrameLayout) v.findViewById(R.id.flContainer);
     flContainer.addView(R.layout.sub_layout);
    return v;
}

but i am getting error near addView the screenshot is below

can anyone please help to find the error

Body:
Replace your onCreateView with the following,

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_start_question, container, false);
    flContainer = (FrameLayout) v.findViewById(R.id.flContainer);
    View subView = inflater.inflate(R.layout.sub_layout, null);
    flContainer.addView(subView);
    return v;
}


问:
Regex to match chars at the start and digits at the end
I need a regular expression for the following conditions:

The length of the string is exactly 8

The string may not start with PAK

The first character must be an upper case char [A-Z]

The second to fourth char can be an upper case char

The remaining chars may only be digits

Examples:

PAK12345 -> not allowed

T1234567 -> allowed

ABCD1234 -> allowed

ABC12345 -> allowed

AB12345A -> not allowed

ABCDE123 -> not allowed

ABC123   -> not allowed

Actually I have the following regex:

```<code>(?!PAK)([A-Z]{1,4}[A-Z0-9]{7})$
</code>```

The problem with this regex is, that "ABCDE123" is a match.

How can I say, that the first 1 to 4 characters are only upper case chars and the remaining (until the total lenght of 8) are digits?

答:
Remove the regex range operator and do an exact character length match. Add a positive lookahead at the very first to ensure that the length must be exactly 8.

```<code>^(?=.{8}$)(?!PAK)([A-Z]{1,4}[0-9]+)$
</code>```

DEMO

Body:
I need a regular expression for the following conditions:

The length of the string is exactly 8

The string may not start with PAK

The first character must be an upper case char [A-Z]

The second to fourth char can be an upper case char

The remaining chars may only be digits

Examples:

PAK12345 -> not allowed

T1234567 -> allowed

ABCD1234 -> allowed

ABC12345 -> allowed

AB12345A -> not allowed

ABCDE123 -> not allowed

ABC123   -> not allowed

Actually I have the following regex:

(?!PAK)([A-Z]{1,4}[A-Z0-9]{7})$

The problem with this regex is, that "ABCDE123" is a match.

How can I say, that the first 1 to 4 characters are only upper case chars and the remaining (until the total lenght of 8) are digits?

Body:
Remove the regex range operator and do an exact character length match. Add a positive lookahead at the very first to ensure that the length must be exactly 8.

^(?=.{8}$)(?!PAK)([A-Z]{1,4}[0-9]+)$

DEMO


问:
datepicker not working on first load, jquery
I am working with datepicker jquery for 2 input "from" and "to" filter.
I want to make it required if one of the filters (from/to) has been selected. And if the user doesn't want to use the date filter, I want to remove the required attribute.

However, after I select a date in my "from" input, the action is not affected on first submit.
Somehow the "from" input didn't recognize value from datepicker on the first load.

Anyone know why it can't work on the first submit?

here is the code for jquery:

```<code>$(document).ready(function () {
    if ($('#to').val().length == 0 && $('#from').val().length == 0) {
        $('#from').removeAttr('required');
        $('#to').removeAttr('required');
    }
    else if ($('#to').val().length > 0 ) {
        $('#from').attr('required');
    }
    else if ($('#from').val().length > 0) {
        $('#to').attr('required');
    }
});
</code>```

for the input from and to, I set it required by default.

```<code> @Html.TextBoxFor(modelitem => Model.startdate, new { @class = "datepicker form-control" ,@placeholder = "Select From Date" , @id="from" , @required = "required" })

 @Html.TextBoxFor(modelitem => Model.finishdate, new { @class = "datepicker form-control", @placeholder = "Select To Date" , @id = "to" , @required = "required" })
</code>```

Please let me know the problem!

答:
try to remove it inside the document.ready function like

```<code><script>
     if ($('#to').val().length == 0 && $('#from').val().length == 0) {
        $('#from').removeAttr('required');
        $('#to').removeAttr('required');
    }
    else if ($('#to').val().length > 0 ) {
        $('#from').attr('required');
    }
    else if ($('#from').val().length > 0) {
        $('#to').attr('required');
    }
</script>
</code>```

or use:

```<code>Alert("this is want to know on first run")
</code>```

inside your if else statement

Addition to:
Right click the page = > console menu on first run and check some errors or any jquery is running or not.

Body:
I am working with datepicker jquery for 2 input "from" and "to" filter.
I want to make it required if one of the filters (from/to) has been selected. And if the user doesn't want to use the date filter, I want to remove the required attribute.

However, after I select a date in my "from" input, the action is not affected on first submit.
Somehow the "from" input didn't recognize value from datepicker on the first load.

Anyone know why it can't work on the first submit?

here is the code for jquery:

$(document).ready(function () {
    if ($('#to').val().length == 0 && $('#from').val().length == 0) {
        $('#from').removeAttr('required');
        $('#to').removeAttr('required');
    }
    else if ($('#to').val().length > 0 ) {
        $('#from').attr('required');
    }
    else if ($('#from').val().length > 0) {
        $('#to').attr('required');
    }
});

for the input from and to, I set it required by default.

 @Html.TextBoxFor(modelitem => Model.startdate, new { @class = "datepicker form-control" ,@placeholder = "Select From Date" , @id="from" , @required = "required" })

 @Html.TextBoxFor(modelitem => Model.finishdate, new { @class = "datepicker form-control", @placeholder = "Select To Date" , @id = "to" , @required = "required" })

Please let me know the problem!

Body:
try to remove it inside the document.ready function like

<script>
     if ($('#to').val().length == 0 && $('#from').val().length == 0) {
        $('#from').removeAttr('required');
        $('#to').removeAttr('required');
    }
    else if ($('#to').val().length > 0 ) {
        $('#from').attr('required');
    }
    else if ($('#from').val().length > 0) {
        $('#to').attr('required');
    }
</script>

or use:

Alert("this is want to know on first run")

inside your if else statement

Addition to:
Right click the page = > console menu on first run and check some errors or any jquery is running or not.


问:
How to remove the gap between navigation icon and toolbar logo?
How can I remove the margin between the navigation icon and toolbar logo.

My toolbar layout

```<code><android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@drawable/paper9patch"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:theme="@style/toolbarTheme"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp">

</android.support.v7.widget.Toolbar>
</code>```

I am inserting logo like this

```<code>   Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
   setSupportActionBar(toolbar);

   toolbar.setContentInsetStartWithNavigation(0);
   getSupportActionBar().setDisplayShowTitleEnabled(false);
   getSupportActionBar().setLogo(R.drawable.sample);
</code>```

my toolbar is looking like this

the logo is almost showing in the middle I want it beside the drawer icon

I searched on stackover flow and all answers tell to use

```<code>app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
</code>```

but its not working . I can say there is no padding for the image it is cropped exactly to edges. If i use tile there is no gap in middle ,the gap appears only when inserted logo.

Is this intended behavior ? Is there any thing else I can do to remove the gap?

Edit : styles i am using

```<code>    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    </style>

   <style name="toolbarTheme" parent="AppTheme">

    <item name="android:textColorPrimary">@color/themeColor</item>
    <item name="android:textColorSecondary">@color/themeColor</item>

    </style>

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</code>```

答:
Try this</p>

```<code><android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@drawable/paper9patch"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:theme="@style/toolbarTheme"
    app:contentInsetLeft="0dp"
    app:contentInsetStart="0dp"
    app:contentInsetStartWithNavigation="0dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@mipmap/ic_launcher_round" />
    </LinearLayout>
</android.support.v7.widget.Toolbar>
</code>```

Body:
How can I remove the margin between the navigation icon and toolbar logo.

My toolbar layout

<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@drawable/paper9patch"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:theme="@style/toolbarTheme"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp">

</android.support.v7.widget.Toolbar>

I am inserting logo like this

   Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
   setSupportActionBar(toolbar);

   toolbar.setContentInsetStartWithNavigation(0);
   getSupportActionBar().setDisplayShowTitleEnabled(false);
   getSupportActionBar().setLogo(R.drawable.sample);

my toolbar is looking like this

the logo is almost showing in the middle I want it beside the drawer icon

I searched on stackover flow and all answers tell to use

app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"

but its not working . I can say there is no padding for the image it is cropped exactly to edges. If i use tile there is no gap in middle ,the gap appears only when inserted logo.

Is this intended behavior ? Is there any thing else I can do to remove the gap?

Edit : styles i am using

Body:
Try this

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@drawable/paper9patch"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:theme="@style/toolbarTheme"
    app:contentInsetLeft="0dp"
    app:contentInsetStart="0dp"
    app:contentInsetStartWithNavigation="0dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@mipmap/ic_launcher_round" />
    </LinearLayout>
</android.support.v7.widget.Toolbar>


问:
Map json Object with randomise array creation
I have JSON object and array

```<code>sampleJson={"id":1,"option1":"","option2":"","option3":""}
sampleArray=["car","","Animals"]
</code>```

i want to add sampleArray to sampleJson in following format

```<code>sampleJson={"id":1,"option1"="car","option2":"Animals","option3":""}
</code>```

sample array will be randomise like ["","car",""] Or ["","animal","Car"]?

答:
```<code>var sampleJson={"id":1,"option1":"","option2":"","option3":""}
var sampleArray=["car","","Animals"]
Object.keys(sampleJson).filter(function(k) {
    return k.includes('option');
}).forEach(function(k,i) {
    if (sampleArray.length > i)
        sampleJson[k] = sampleArray[i];
});
console.log(sampleJson)
</code>```

Hope it helps!!

Body:
I have JSON object and array

sampleJson={"id":1,"option1":"","option2":"","option3":""}
sampleArray=["car","","Animals"]

i want to add sampleArray to sampleJson in following format

sampleJson={"id":1,"option1"="car","option2":"Animals","option3":""}

sample array will be randomise like ["","car",""] Or ["","animal","Car"]?

Body:
var sampleJson={"id":1,"option1":"","option2":"","option3":""}
var sampleArray=["car","","Animals"]
Object.keys(sampleJson).filter(function(k) {
    return k.includes('option');
}).forEach(function(k,i) {
    if (sampleArray.length > i)
        sampleJson[k] = sampleArray[i];
});
console.log(sampleJson)

Hope it helps!!


答: Use a StringBuilder and append the content as you create the email, if the funstion takes a String, just pass the StringBuilder with toString()</p>

Title: Java - String value is getting break when doing a concat


问:
Laravel passport oauth multiple database connection
So, I'm building this api where each client use the same system (controllers, models). Each client has his own database and a website that connect's to this database.

Now that's the problem, this api must serve all this websites with different database connections and since I'm new to Laravel, I'm facing a hard time. What's the best way to do that?

Should I save each database in a file (for example client's id is 1, so we have a folder with a file named 1.env with database info)?

PS.: I'm using oauth2

答:
The solution I found was: each client with his own database and a folder with "users" and a subfolder for each client. Inside, a file with database info, in login we use a global table that indicates where's the database from that user. Next step is load the database connection and check user/password. That was a quick solution.

However in my research  I stumped into "multi tenancy" thing that seams way better, you can find it more on this link.


答:
This is an easy exercise of just a few clicks with Power Query. Power Query is a free add-in from Microsoft for Excel 2010 and 2013 and built into Excel 2016 as Get and Transform.

Load the dataset into Powerquery (either from a file or from a table in your Excel workbook), select the year column and execute the command "unpivot other columns".

That will sort the data into three columns, i.e. year, "attribute" and value. Rename the attribute  column to "month".

Next use the command to insert a new column by example, then type out "1-Jan-2001" and "1-Feb-2001" as the first two examples.

Power Query will then fill the column with the correct values. Parse the values as dates, so they are real dates. remove the columns you no longer need and save the query. You can format the date column to show just year and month.

If you can't or don't want to use Power Pivot, you can use a reverse pivot like this:

select the data

open the pivot wizard with Alt-D-P

click "multiple consolidation ranges" > Next

click "I will create the page fields" > Next

select the data in the sheet and click Add, then > Next

Click Finish

in the new pivot table, drag the fields out of the rows and columns area to remove them. That leaves you with a single value.

double click the number

the flat table of all values will be in a new sheet

rename the columns as desired

to create a single column for the date, use this formula

=DATEVALUE("1-"&[@month]&"-"&[@year])

Adjust the formula to a text that is recognised in your region as a date and copy down. Copy the column with formulas and paste as values. Format the date to show only year and month. Delete the columns you don't need.

The beauty of the Power Query approach is that it can be repeated with a fresh data set with just one click, whereas the Pivot table approach requires you to go through all the steps each time.

Edit: I added steps to create real dates in one column. Note that the extra steps to create real dates as opposed to just text like "2001-Jan" are worth the work. The benefit is that real dates play much nicer in data sorting, pivots and chart axes. Enjoy.

Title: Not sure how to convert the data in an xlsx file into monthly by year data without rewriting the whole dataset

Body:
Here is the dataset
Table B.21  Arizona Average Retail Price of Residential Electricity (Cents per kWh)

Source:  http://www.eia.gov/electricity/data.cfm#sales

Year    Jan     Feb     Mar     Apr     May     Jun     Jul     Aug     Sep     Oct     Nov     Dec
2001    6.99    7.13    7.4     8.09    9.41    9.04    8.84    8.84    8.81    8.95    7.17    7.26
2002    7.01    7.17    7.46    7.69    9.37    8.97    8.65    8.78    8.79    8.99    7.37    7.46
2003    7.06    7.57    7.59    7.82    9.52    9.09    8.78    8.74    8.7     8.83    7.21    7.55
2004    7.27    7.49    7.61    8.05    9.26    9.1     8.88    8.87    8.96    8.79    8.05    7.86
2005    7.75    7.99    8.19    8.67    9.6     9.41    9.3     9.28    9.3     9.23    8.12    7.88
2006    8.05    8.21    8.38    8.92    10.19   10.05   9.9     9.88    9.89    9.88    8.74    8.56
2007    8.33    8.46    8.8     9.19    10.2    9.96    10.37   10.33   10.17   10.16   9.08    8.89
2008    8.85    9.02    9.38    10.02   11.03   11.06   10.95   10.86   10.63   10.46   9.55    9.61
2009    9.51    9.82    9.93    10.65   11.33   11.27   11.3    11.29   11.17   10.97   9.86    9.7
2010    9.57    9.84    9.98    10.24   11.75   11.74   11.78   11.59   11.52   10.96   10.14   10
2011    9.84    9.93    10.25   10.97   11.77   11.77   11.85   11.67   11.53   11.08   10.31   9.98
2012    10.01   10.26   10.44   11.17   11.88   11.9    11.86   11.83   11.66   11.36   10.73   10.41
2013    10.25   10.7    10.87   11.74   12.17   12.18   12.51   12.33   12.22   12.02   11.06   11.01
2014    10.92   11.23   11.32   11.97   -   -   -   -   -   -   -   -

and it is xlsx format.  Is there a way to re-format it to where it is two columns, one of which is the month-year, and the second is the observation?  The conversion of the dataset is not a problem that is for any class, but I need to use it for time series analysis, and am trying to put it in a format to be able to accomplish that.

Thank you for any help you can provide.

Adam


问:
Regular expression to match US phone numbers
The regular expression ^((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}$ matches strings of the form XXX-XXX-XXXX and XXX-XXXX (am I missing out something?).

It doesn't, however, match (XXX) XXX-XXXX and (XXX) XXX-XXX-XXXX as well (which I need it to match).

Can you help me fix it so that it matches the formats

XXX-XXX-XXXX,
XXX-XXXX,
(XXX) XXX-XXXX,
(XXX) XXX-XXXX

without causing it to match other string formats which I don't want?

Body:
^(((\d{3}) ?)|(\d{3}-))?\d{3}-\d{4}$^

this will work.


问:
UITextField text change event
How can I detect any text changes in a textField? The delegate method shouldChangeCharactersInRange works for something, but it did not fulfill my need exactly. Since until it returns YES, the textField texts are not available to other observer methods.

e.g. in my code calculateAndUpdateTextFields did not get the updated text, the user has typed.

Is their any way to get something like textChanged Java event handler.

```<code>- (BOOL)textField:(UITextField *)textField
            shouldChangeCharactersInRange:(NSRange)range
            replacementString:(NSString *)string
{
    if (textField.tag == kTextFieldTagSubtotal
        || textField.tag == kTextFieldTagSubtotalDecimal
        || textField.tag == kTextFieldTagShipping
        || textField.tag == kTextFieldTagShippingDecimal)
    {
        [self calculateAndUpdateTextFields];

    }

    return YES;
}
</code>```

答:
Swift 3 Version

```<code>yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged)
</code>```

And get the changes in here

```<code>func textChanges(_ textField: UITextField) {
    let text = textField.text! // your desired text here
    // Now do whatever you want.
}
</code>```

Hope it helps.

Title: UITextField text change event

Body:
How can I detect any text changes in a textField? The delegate method shouldChangeCharactersInRange works for something, but it did not fulfill my need exactly. Since until it returns YES, the textField texts are not available to other observer methods.

e.g. in my code calculateAndUpdateTextFields did not get the updated text, the user has typed.

Is their any way to get something like textChanged Java event handler.

- (BOOL)textField:(UITextField *)textField
            shouldChangeCharactersInRange:(NSRange)range
            replacementString:(NSString *)string
{
    if (textField.tag == kTextFieldTagSubtotal
        || textField.tag == kTextFieldTagSubtotalDecimal
        || textField.tag == kTextFieldTagShipping
        || textField.tag == kTextFieldTagShippingDecimal)
    {
        [self calculateAndUpdateTextFields];

    }

    return YES;
}

Body:
Swift 3 Version

yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged)

And get the changes in here

func textChanges(_ textField: UITextField) {
    let text = textField.text! // your desired text here
    // Now do whatever you want.
}

Hope it helps.


问:
vectorize a function on 2 python objects
I would like to vectorize a function that takes 2 objects as argument such that it takes 2 ndarrays (of length m and n) and returns a matrix of shape (m x n).
Kinda like a tensor product.

I've tried to use numpy.vectorize without much success:

```<code>vFunc = np.vectorize(myFunc)
arg1 = np.asmatrix(a)
arg2 = np.transpose(np.asmatrix(b))
test = vFunc(arg1,arg2)
</code>```

The above doesn't work, so for now I have to iterate on one of the arrays, which is an ugly solution. How do I fix this?

```<code>vFunc = np.vectorize(myFunc)
arg1 = np.asmatrix(a)
arg2 = np.transpose(np.asmatrix(b))
for i in range(arg1.size): cMat[i,] = vFunc(arg1[i],arg2)
</code>```

答:
This is the basic vectorize setup:

```<code>In [420]: def myfunc(x,y):
     ...:     return 10*x + y
     ...:
In [421]: f = np.vectorize(myfunc)
In [422]: f(np.arange(4), np.arange(3)[:,None])
Out[422]:
array([[ 0, 10, 20, 30],
       [ 1, 11, 21, 31],
       [ 2, 12, 22, 32]])
</code>```

How is your case different?  Don't just say 'it doesn't work'!

With this particular function, I don't even need vectorize:

```<code>In [423]: myfunc(np.arange(4), np.arange(3)[:,None])
Out[423]:
array([[ 0, 10, 20, 30],
       [ 1, 11, 21, 31],
       [ 2, 12, 22, 32]])
</code>```

The actions within myfunc already work fine with broadcasting

myfunc(np.asmatrix(np.arange(4)), np.asmatrix(np.arange(3)).T) also works, but the conversion to matrix isn't needed, and is generally discouraged.

Body:
I would like to vectorize a function that takes 2 objects as argument such that it takes 2 ndarrays (of length m and n) and returns a matrix of shape (m x n).
Kinda like a tensor product.

I've tried to use numpy.vectorize without much success:

vFunc = np.vectorize(myFunc)
arg1 = np.asmatrix(a)
arg2 = np.transpose(np.asmatrix(b))
test = vFunc(arg1,arg2)

The above doesn't work, so for now I have to iterate on one of the arrays, which is an ugly solution. How do I fix this?

vFunc = np.vectorize(myFunc)
arg1 = np.asmatrix(a)
arg2 = np.transpose(np.asmatrix(b))
for i in range(arg1.size): cMat[i,] = vFunc(arg1[i],arg2)

Body:
This is the basic vectorize setup:

In [420]: def myfunc(x,y):
     ...:     return 10*x + y
     ...:
In [421]: f = np.vectorize(myfunc)
In [422]: f(np.arange(4), np.arange(3)[:,None])
Out[422]:
array([[ 0, 10, 20, 30],
       [ 1, 11, 21, 31],
       [ 2, 12, 22, 32]])

How is your case different?  Don't just say 'it doesn't work'!

With this particular function, I don't even need vectorize:

In [423]: myfunc(np.arange(4), np.arange(3)[:,None])
Out[423]:
array([[ 0, 10, 20, 30],
       [ 1, 11, 21, 31],
       [ 2, 12, 22, 32]])

The actions within myfunc already work fine with broadcasting

myfunc(np.asmatrix(np.arange(4)), np.asmatrix(np.arange(3)).T) also works, but the conversion to matrix isn't needed, and is generally discouraged.


问:
Why Inflector::slug in Yii2 generates wrong latin string from cyrillic?
Inflector::slug in Yii2 generates not correct string from cyrillic.

Example: автоматизация -> avtomatizacia, but it must be avtomatizaciya; зачислить -> zacislit, but it must be zachislit. How to fix it?

I use this for SEO urls. Can this influence if search engines will not recognise the correct keyword to improve SEO results for my website?

答:
Because it uses ISO 9 for handling  cyrillic and aparently its ISO 9:1995 version.
Now when I put:

```<code>echo \yii\helpers\Inflector::transliterate('автоматизация', 'Cyrillic;  Any-Latin');
echo yii\helpers\Inflector::transliterate('зачислить', $a);
</code>```

I get:

```<code>avtomatizaciâ
začislitʹ
</code>```

Which is as in ISO 9:1995. Slug method does conversion to ASCII character to charcter and so for example č gets changed into c.

You can still do as you want just str-replace where needed.
Or you can do the transliteration another way like this.

Body:
Because it uses ISO 9 for handling  cyrillic and aparently its ISO 9:1995 version.
Now when I put:

echo \yii\helpers\Inflector::transliterate('автоматизация', 'Cyrillic;  Any-Latin');
echo yii\helpers\Inflector::transliterate('зачислить', $a);

I get:

avtomatizaciâ
začislitʹ

Which is as in ISO 9:1995. Slug method does conversion to ASCII character to charcter and so for example č gets changed into c.

You can still do as you want just str-replace where needed.
Or you can do the transliteration another way like this.


问:
Numpy outer addition of subarrays
Is there a way, in numpy, to perform what amounts to an outer addition of subarrays?

That is to say, I have 2 arrays of the form 2x2xNxM, which may each be considered a stack of 2x2 matrices N high and M wide. I would like to add each of these matrices to each matrix from the other array, to form a 2x2xNxMxNxM array in which the last four indices correspond to the indices in my initial two arrays so that I can index output[:,:,x1,y1,x2,y2] == a1[:,:,x1,y1] + a2[:,:,x2,y2].

If these were arrays of scalars, it would be trivial, all I'd have to do is:

```<code>A, B = a.ravel(), b.ravel()
four_D = (a[...:np.newaxis] + b).reshape(*a1.shape, *a2.shape)

for (x1, y1, x2, y2), added in np.ndenumerate(four_D):
    assert added == a1[x1,y1] + a2[x2,y2]
</code>```

However, this doesn't work for the case where a and b comprise of matrices. I could, of course, use nested for loops, but my dataset is going to be fairly large, and I'm expecting to run this over multiple datasets.

Is there an efficient way to do this?

答:
Extend arrays to have more dimensions and then leverage broadcasting -

```<code>output = a1[...,None,None] + a2[...,None,None,:,:]
</code>```

Sample run -

```<code>In [38]: # Setup input arrays
    ...: N = 3
    ...: M = 4
    ...: a1 = np.random.rand(2,2,N,M)
    ...: a2 = np.random.rand(2,2,N,M)
    ...:
    ...: output = np.zeros((2,2,N,M,N,M))
    ...: for x1 in range(N):
    ...:     for x2 in range(N):
    ...:         for y1 in range(M):
    ...:             for y2 in range(M):
    ...:                 output[:,:,x1,y1,x2,y2] = a1[:,:,x1,y1] + a2[:,:,x2,y2]
    ...:
    ...: output1 = a1[...,None,None] + a2[...,None,None,:,:]
    ...:
    ...: print np.allclose(output, output1)
True
</code>```

Title: Numpy outer addition of subarrays

Body:
Is there a way, in numpy, to perform what amounts to an outer addition of subarrays?

That is to say, I have 2 arrays of the form 2x2xNxM, which may each be considered a stack of 2x2 matrices N high and M wide. I would like to add each of these matrices to each matrix from the other array, to form a 2x2xNxMxNxM array in which the last four indices correspond to the indices in my initial two arrays so that I can index output[:,:,x1,y1,x2,y2] == a1[:,:,x1,y1] + a2[:,:,x2,y2].

If these were arrays of scalars, it would be trivial, all I'd have to do is:

A, B = a.ravel(), b.ravel()
four_D = (a[...:np.newaxis] + b).reshape(*a1.shape, *a2.shape)

for (x1, y1, x2, y2), added in np.ndenumerate(four_D):
    assert added == a1[x1,y1] + a2[x2,y2]

However, this doesn't work for the case where a and b comprise of matrices. I could, of course, use nested for loops, but my dataset is going to be fairly large, and I'm expecting to run this over multiple datasets.

Is there an efficient way to do this?

Body:
Extend arrays to have more dimensions and then leverage broadcasting -

output = a1[...,None,None] + a2[...,None,None,:,:]

Sample run -

In [38]: # Setup input arrays
    ...: N = 3
    ...: M = 4
    ...: a1 = np.random.rand(2,2,N,M)
    ...: a2 = np.random.rand(2,2,N,M)
    ...:
    ...: output = np.zeros((2,2,N,M,N,M))
    ...: for x1 in range(N):
    ...:     for x2 in range(N):
    ...:         for y1 in range(M):
    ...:             for y2 in range(M):
    ...:                 output[:,:,x1,y1,x2,y2] = a1[:,:,x1,y1] + a2[:,:,x2,y2]
    ...:
    ...: output1 = a1[...,None,None] + a2[...,None,None,:,:]
    ...:
    ...: print np.allclose(output, output1)
True


答:
Same as for scalars inserting additional axes works for higher dimensional arrays too (this is called broadcasting): </p>

```<code>import numpy as np

a1 = np.random.randn(2, 2, 3, 4)
a2 = np.random.randn(2, 2, 3, 4)
added = a1[..., np.newaxis, np.newaxis] + a2[..., np.newaxis, np.newaxis, :, :]

print(added.shape)  # (2, 2, 3, 4, 3, 4)
</code>```

Title: Numpy outer addition of subarrays

Body:
Same as for scalars inserting additional axes works for higher dimensional arrays too (this is called broadcasting):

import numpy as np

a1 = np.random.randn(2, 2, 3, 4)
a2 = np.random.randn(2, 2, 3, 4)
added = a1[..., np.newaxis, np.newaxis] + a2[..., np.newaxis, np.newaxis, :, :]

print(added.shape)  # (2, 2, 3, 4, 3, 4)


问:
JMeter extract link using regular expression pass into next request with blank values
This is how I have Test Plan set up:

HTTP Request -> Regular Expression Extractor to extract multiple links  - This is extracting correctly -- But some of the links are Blank
RegularExpressionExtractor ---

BeanShell Sampler - to filter blank or null values -- This works fine

BeanShell Sampler

```<code>log.info("Enter Beanshell Sampler");
matches = vars.get("url_matchNr");
log.info(matches);

for (Integer i=1; i < Integer.parseInt(matches); i++)
{
    String url = vars.get("url_"+i);
    //log.info(url1);
    if(url != null @and url.length() > 0)
    {
        log.info(i+"->" + url);
        //return url;
        //vars.put("url2", url);
        vars.put("url2", url);
        //props.put("url2", url);
        log.info("URL2:" + vars.get("url2"));
    }
}
</code>```

ForEach Controller
ForEach Controller

href="https://i.stack.imgur.com/Knomw.png" rel="nofollow noreferrer">Test Plan

The problem I am facing is ForEach Controller runs through all the values including Blank or NULL -- How can I run the loop only for the non null blank values

答:
As mentioned earlier, you should change your regex!

you can replace it directly by

```<code><a href="(.+)" class="product-link">
</code>```

or by something more constraining like this:

```<code><a href="^((https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?)$" class="product-link">
</code>```

which is a regex to match only URLs.

https://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149

The first capturing group is all option. It allows the URL to begin
  with "http://", "https://", or neither of them. I have a question mark
  after the s to allow URL's that have http or https. In order to make
  this entire group optional, I just added a question mark to the end of
  it.

Next is the domain name: one or more numbers, letters, dots, or hypens
  followed by another dot then two to six letters or dots. The following
  section is the optional files and directories. Inside the group, we
  want to match any number of forward slashes, letters, numbers,
  underscores, spaces, dots, or hyphens. Then we say that this group can
  be matched as many times as we want. Pretty much this allows multiple
  directories to be matched along with a file at the end. I have used
  the star instead of the question mark because the star says zero or
  more, not zero or one. If a question mark was to be used there, only
  one file/directory would be able to be matched.

Then a trailing slash is matched, but it can be optional. Finally we
  end with the end of the line.

String that matches:

http://net.tutsplus.com/about

String that doesn't match:

http://google.com/some/file!.html (contains an exclamation point)

Good luck!!!

Body:
This is how I have Test Plan set up:

HTTP Request -> Regular Expression Extractor to extract multiple links  - This is extracting correctly -- But some of the links are Blank
RegularExpressionExtractor ---

BeanShell Sampler - to filter blank or null values -- This works fine

BeanShell Sampler

log.info("Enter Beanshell Sampler");
matches = vars.get("url_matchNr");
log.info(matches);

for (Integer i=1; i < Integer.parseInt(matches); i++)
{
    String url = vars.get("url_"+i);
    //log.info(url1);
    if(url != null @and url.length() > 0)
    {
        log.info(i+"->" + url);
        //return url;
        //vars.put("url2", url);
        vars.put("url2", url);
        //props.put("url2", url);
        log.info("URL2:" + vars.get("url2"));
    }
}

ForEach Controller
ForEach Controller

Test Plan

The problem I am facing is ForEach Controller runs through all the values including Blank or NULL -- How can I run the loop only for the non null blank values

Body:
As mentioned earlier, you should change your regex!

you can replace it directly by

<a href="(.+)" class="product-link">

or by something more constraining like this:

<a href="^((https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?)$" class="product-link">

which is a regex to match only URLs.

https://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149

The first capturing group is all option. It allows the URL to begin
  with "http://", "https://", or neither of them. I have a question mark
  after the s to allow URL's that have http or https. In order to make
  this entire group optional, I just added a question mark to the end of
  it.

Next is the domain name: one or more numbers, letters, dots, or hypens
  followed by another dot then two to six letters or dots. The following
  section is the optional files and directories. Inside the group, we
  want to match any number of forward slashes, letters, numbers,
  underscores, spaces, dots, or hyphens. Then we say that this group can
  be matched as many times as we want. Pretty much this allows multiple
  directories to be matched along with a file at the end. I have used
  the star instead of the question mark because the star says zero or
  more, not zero or one. If a question mark was to be used there, only
  one file/directory would be able to be matched.

Then a trailing slash is matched, but it can be optional. Finally we
  end with the end of the line.

String that matches:

http://net.tutsplus.com/about

String that doesn't match:

http://google.com/some/file!.html (contains an exclamation point)

Good luck!!!


问:
Rotate a moving shape around its center
I'm making a 2D game in Java where the player guides a polygon through obstacles. The polygon moves up and down and the game world scrolls left and right. I need the polygon to rotate around its center, but since it is constantly being translated the point it is being rotated around moves. Trying to translate it back to the original center, rotate it, and translate it back doesn't work. How do I get the center of the shape?

Here are my motion calculations on a 2ms timer:

```<code>@Override
public void actionPerformed(ActionEvent e) {

    double theta = angleRad+90;
    if (up == true) {
        if (accelerating == false) {
            time2 = 0;
            moveX0 = moveX;
            moveY0 = moveY;
            accelerating = true;
        }
        time1++;
        double t = time1/500;
        if (accCount % 10 == 0) {
            DronePilot.velocity++;
        }
        moveX = moveX0 + velX*Math.cos(theta)*t;
        moveY = moveY0 + velY*Math.sin(theta)*t-(1/2d)*g*Math.pow(t, 2);
        velX = (DronePilot.velocity)*Math.cos(theta);
        velY = (DronePilot.velocity)*Math.sin(theta)-g*(t);
        accCount++;
    } else if (up == false){
        if (accelerating == true) {
            time1 = 0;
            moveX0 = moveX;
            moveY0 = moveY;
            accelerating = false;
        }
        time2++;
        double t = time2/500;
        moveX = moveX0 + velX*Math.cos(theta)*t;
        moveY = moveY0 + velY*Math.sin(theta)*t-(1/2d)*g*Math.pow(t, 2);
        accCount = 0;
    } if (left == true) {
        angleCount++;
        if (angleCount % 2 == 0) {
            angleDeg++;
        }
        angleRad = Math.toRadians(angleDeg);
    } else if (right == true) {
        angleCount--;
        if (angleCount % 2 == 0) {
            angleDeg--;
        }
        angleRad = Math.toRadians(angleDeg);
    }
    repaint();
}
}
</code>```

And here is my paintComponent method:

```<code>@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D)g;

    Graphics g2 = g.create();
    Graphics2D copy = (Graphics2D)g2;

    copy.rotate(-angleRad, xPos, yPos);

    copy.translate(0, -moveY);

    g2D.translate(-moveX, 0);

    copy.draw(player.shape);

    for (Rectangle2D.Double r: DronePilot.rocksFloorArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.rocksCeilArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.roomsArray) {
        g2D.draw(r);
    }
}
</code>```

where (xPos, yPos) are the center of the screen.

答:
Transformations are (normally) compounding

```<code>public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D)g;

    Graphics g2 = g.create();
    Graphics2D copy = (Graphics2D)g2;

    copy.rotate(-angleRad, xPos, yPos);
    copy.translate(0, -moveY);

    g2D.translate(-moveX, 0);

    copy.draw(player.shape);
    for (Rectangle2D.Double r: DronePilot.rocksFloorArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.rocksCeilArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.roomsArray) {
        g2D.draw(r);
    }
}
</code>```

In your above code, you are translating both the original Graphics context and the copy.  In this context, copy won't be affected by the original and the original won't be affected by the copy, BUT, the original context is a shared resource and since you don't reset the translation, you will continue to get a translated context each time (compounding).

As a general rule of thumb, do ALL transformations on a copy and dispose of it when you're done.

For example...

```<code>Graphics2D g2d = (Graphics2D)g.create();
AffineTransform at = AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y);
at.rotate(Math.toRadians(angle), player.getBounds2D().getCenterX(), player.getBounds2D().getCenterY());
g2d.setTransform(at);
g2d.setColor(Color.RED);
g2d.fill(player);
g2d.setColor(Color.BLACK);
g2d.draw(player);
g2d.dispose();
</code>```

This basically translates the position of the object to the player's position and then rotates the object about the centre of the object

You could, also, apply one transformation, create a copy of that context and apply another transformation, which would become compounded (so you could translate one context, copy it, and then rotate the copy and the first translation would still applied to the copy)

This incredible simple example demonstrates two basic example...

Using the Graphics context and a AffineTransform to translate and rotate the player object (about it's centre point)

Using a Path2D to generate a transformed shape (this example makes two objects, but you could use a single AffineTransform translated and rotated and apply it once).

In both cases, they don't affect the original shape

```<code>import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Shape player;
        private Point playerPoint;
        private float angle;
        private float deltaZ = 1.0f;

        private int deltaX, deltaY;

        public TestPane() {
            player = new Rectangle(0, 0, 20, 20);
            playerPoint = new Point(80, 80);
            Random rnd = new Random();
            deltaX = 1;
            deltaY = -1;

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    playerPoint.x += deltaX;
                    playerPoint.y += deltaY;

                    Shape rotatedPlayer = rotatedAndTranslatedPlayer();
                    Rectangle2D bounds = rotatedPlayer.getBounds2D();
                    if (bounds.getX() < 0.0) {
                        playerPoint.x = (int)(bounds.getX() * -1);
                        deltaX *= -1;
                    } else if (bounds.getX() + bounds.getWidth() >= getWidth()) {
                        playerPoint.x = getWidth() - (int)bounds.getWidth();
                        deltaX *= -1;
                    }
                    if (bounds.getY() < 0) {
                        playerPoint.y = 0;
                        deltaY *= -1;
                    } else if (bounds.getY() + bounds.getHeight() > getHeight()) {
                        playerPoint.y = getHeight() - (int)bounds.getHeight();
                        deltaY *= -1;
                    }
                    angle += deltaZ;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected Shape rotatedAndTranslatedPlayer() {
            Path2D.Double rotated = new Path2D.Double(player,  AffineTransform.getRotateInstance(
                    Math.toRadians(angle),
                    player.getBounds2D().getCenterX(),
                    player.getBounds2D().getCenterY()));
            return new Path2D.Double(rotated, AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y));
        }

        // Simply paints the "area" that the player takes up when it's rotated and
        // translated
        protected void paintAutoTranslatedShape(Graphics2D g2d) {
            g2d.setColor(Color.DARK_GRAY);
            g2d.fill(rotatedAndTranslatedPlayer().getBounds2D());
        }

        // Uses a AffineTransform to translate and rotate the player
        protected void paintPlayer(Graphics2D g2d) {
            AffineTransform at = AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y);
            at.rotate(Math.toRadians(angle), player.getBounds2D().getCenterX(), player.getBounds2D().getCenterY());
            g2d.setTransform(at);
            g2d.setColor(Color.RED);
            g2d.fill(player);
            g2d.setColor(Color.BLACK);
            g2d.draw(player);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            paintAutoTranslatedShape(g2d);
            g2d.dispose();
            g2d = (Graphics2D) g.create();
            paintPlayer(g2d);
            g2d.dispose();
        }

    }
}
</code>```

Title: Rotate a moving shape around its center

Body:
I'm making a 2D game in Java where the player guides a polygon through obstacles. The polygon moves up and down and the game world scrolls left and right. I need the polygon to rotate around its center, but since it is constantly being translated the point it is being rotated around moves. Trying to translate it back to the original center, rotate it, and translate it back doesn't work. How do I get the center of the shape?

Here are my motion calculations on a 2ms timer:

@Override
public void actionPerformed(ActionEvent e) {

    double theta = angleRad+90;
    if (up == true) {
        if (accelerating == false) {
            time2 = 0;
            moveX0 = moveX;
            moveY0 = moveY;
            accelerating = true;
        }
        time1++;
        double t = time1/500;
        if (accCount % 10 == 0) {
            DronePilot.velocity++;
        }
        moveX = moveX0 + velX*Math.cos(theta)*t;
        moveY = moveY0 + velY*Math.sin(theta)*t-(1/2d)*g*Math.pow(t, 2);
        velX = (DronePilot.velocity)*Math.cos(theta);
        velY = (DronePilot.velocity)*Math.sin(theta)-g*(t);
        accCount++;
    } else if (up == false){
        if (accelerating == true) {
            time1 = 0;
            moveX0 = moveX;
            moveY0 = moveY;
            accelerating = false;
        }
        time2++;
        double t = time2/500;
        moveX = moveX0 + velX*Math.cos(theta)*t;
        moveY = moveY0 + velY*Math.sin(theta)*t-(1/2d)*g*Math.pow(t, 2);
        accCount = 0;
    } if (left == true) {
        angleCount++;
        if (angleCount % 2 == 0) {
            angleDeg++;
        }
        angleRad = Math.toRadians(angleDeg);
    } else if (right == true) {
        angleCount--;
        if (angleCount % 2 == 0) {
            angleDeg--;
        }
        angleRad = Math.toRadians(angleDeg);
    }
    repaint();
}
}

And here is my paintComponent method:

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D)g;

    Graphics g2 = g.create();
    Graphics2D copy = (Graphics2D)g2;

    copy.rotate(-angleRad, xPos, yPos);

    copy.translate(0, -moveY);

    g2D.translate(-moveX, 0);

    copy.draw(player.shape);

    for (Rectangle2D.Double r: DronePilot.rocksFloorArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.rocksCeilArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.roomsArray) {
        g2D.draw(r);
    }
}

where (xPos, yPos) are the center of the screen.

Body:
Transformations are (normally) compounding

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D)g;

    Graphics g2 = g.create();
    Graphics2D copy = (Graphics2D)g2;

    copy.rotate(-angleRad, xPos, yPos);
    copy.translate(0, -moveY);

    g2D.translate(-moveX, 0);

    copy.draw(player.shape);
    for (Rectangle2D.Double r: DronePilot.rocksFloorArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.rocksCeilArray) {
        g2D.draw(r);
    }
    for (Rectangle2D.Double r: DronePilot.roomsArray) {
        g2D.draw(r);
    }
}

In your above code, you are translating both the original Graphics context and the copy.  In this context, copy won't be affected by the original and the original won't be affected by the copy, BUT, the original context is a shared resource and since you don't reset the translation, you will continue to get a translated context each time (compounding).

As a general rule of thumb, do ALL transformations on a copy and dispose of it when you're done.

For example...

Graphics2D g2d = (Graphics2D)g.create();
AffineTransform at = AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y);
at.rotate(Math.toRadians(angle), player.getBounds2D().getCenterX(), player.getBounds2D().getCenterY());
g2d.setTransform(at);
g2d.setColor(Color.RED);
g2d.fill(player);
g2d.setColor(Color.BLACK);
g2d.draw(player);
g2d.dispose();

This basically translates the position of the object to the player's position and then rotates the object about the centre of the object

You could, also, apply one transformation, create a copy of that context and apply another transformation, which would become compounded (so you could translate one context, copy it, and then rotate the copy and the first translation would still applied to the copy)

This incredible simple example demonstrates two basic example...

Using the Graphics context and a AffineTransform to translate and rotate the player object (about it's centre point)

Using a Path2D to generate a transformed shape (this example makes two objects, but you could use a single AffineTransform translated and rotated and apply it once).

In both cases, they don't affect the original shape

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Shape player;
        private Point playerPoint;
        private float angle;
        private float deltaZ = 1.0f;

        private int deltaX, deltaY;

        public TestPane() {
            player = new Rectangle(0, 0, 20, 20);
            playerPoint = new Point(80, 80);
            Random rnd = new Random();
            deltaX = 1;
            deltaY = -1;

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    playerPoint.x += deltaX;
                    playerPoint.y += deltaY;

                    Shape rotatedPlayer = rotatedAndTranslatedPlayer();
                    Rectangle2D bounds = rotatedPlayer.getBounds2D();
                    if (bounds.getX() < 0.0) {
                        playerPoint.x = (int)(bounds.getX() * -1);
                        deltaX *= -1;
                    } else if (bounds.getX() + bounds.getWidth() >= getWidth()) {
                        playerPoint.x = getWidth() - (int)bounds.getWidth();
                        deltaX *= -1;
                    }
                    if (bounds.getY() < 0) {
                        playerPoint.y = 0;
                        deltaY *= -1;
                    } else if (bounds.getY() + bounds.getHeight() > getHeight()) {
                        playerPoint.y = getHeight() - (int)bounds.getHeight();
                        deltaY *= -1;
                    }
                    angle += deltaZ;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected Shape rotatedAndTranslatedPlayer() {
            Path2D.Double rotated = new Path2D.Double(player,  AffineTransform.getRotateInstance(
                    Math.toRadians(angle),
                    player.getBounds2D().getCenterX(),
                    player.getBounds2D().getCenterY()));
            return new Path2D.Double(rotated, AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y));
        }

        // Simply paints the "area" that the player takes up when it's rotated and
        // translated
        protected void paintAutoTranslatedShape(Graphics2D g2d) {
            g2d.setColor(Color.DARK_GRAY);
            g2d.fill(rotatedAndTranslatedPlayer().getBounds2D());
        }

        // Uses a AffineTransform to translate and rotate the player
        protected void paintPlayer(Graphics2D g2d) {
            AffineTransform at = AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y);
            at.rotate(Math.toRadians(angle), player.getBounds2D().getCenterX(), player.getBounds2D().getCenterY());
            g2d.setTransform(at);
            g2d.setColor(Color.RED);
            g2d.fill(player);
            g2d.setColor(Color.BLACK);
            g2d.draw(player);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            paintAutoTranslatedShape(g2d);
            g2d.dispose();
            g2d = (Graphics2D) g.create();
            paintPlayer(g2d);
            g2d.dispose();
        }

    }
}


问:
How to access gmail and read the content of the email using UFT
After I complete an order, system will send a temp password to gmail account. It will take about 20 minutes for the email to be sent. Then I will have to read the email content and get the temp password.

Example:

Script clicks submit button.

wait 20 minutes

Access gmail and look for the email coming from xyz company.

If email arrived, parse the temp password to a  variable.

Sample email:

Email subject: Your temp pw

Email body:

Dear sdfsf sdfsdf,

Thank you for registering for the nnn.

Your temporary password is: Drhh5JT

Your temporary password to log in, https://examplesite.com/, and then reset
your password.

Your temporary password will expire in 4 hours.

If you have questions, call us at 666-666-6666

Thank you, The xyz

How can I accomplish this using UFT?

答:
Once you navigate to your required email and open it. You need to copy Frame source in a Notepad file (this can be achieved by right click > Select "View Frame Source")

once it is copied as text file you can simply use FileSystemObject to read it and search for 'Temporary Password' and retrieve it.

Alternatively you can add this mail account in MS Outlook and use Outlook.application for achieving the same.


问:
Tracking MySQL Database Changes
I'm running MySQL 5.1.36 and have a database used for a web-based help desk system. The database has three tables I'd like to track changes for:

```<code>CREATE TABLE IF NOT EXISTS `tickets` (
  `TicketNum` int(11) unsigned NOT NULL,
  `SubmittedFromIP` tinyblob,
  `SubmittedFromDevice` varchar(255) DEFAULT NULL,
  `EntryDate` datetime DEFAULT NULL,
  `ClosedDate` datetime DEFAULT NULL,
  `LastName` varchar(50) DEFAULT NULL,
  `FirstName` varchar(50) DEFAULT NULL,
  `Email` varchar(50) DEFAULT NULL,
  `Location` varchar(4) DEFAULT NULL,
  `InventoryNumber` varchar(50) DEFAULT NULL,
  `DeviceName` varchar(50) DEFAULT NULL,
  `Description` text,
  `Notes` text,
  `Agent_ID` smallint(5) unsigned NOT NULL DEFAULT '1',
  `TotalHoursSpent` float NOT NULL DEFAULT '0',
  `Status` smallint(5) unsigned NOT NULL DEFAULT '1',
  `Priority` tinyint(4) NOT NULL DEFAULT '0',
  `LastUpdatedByAgent_ID` smallint(5) unsigned DEFAULT NULL,
  PRIMARY KEY (`TicketNum`),
  KEY `ClosedDate` (`ClosedDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `ticketsolutions` (
  `Entry_ID` int(10) unsigned NOT NULL,
  `TicketNum` mediumint(8) unsigned DEFAULT NULL,
  `EntryDateTime` datetime DEFAULT NULL,
  `HoursSpent` float DEFAULT NULL,
  `Agent_ID` smallint(5) unsigned DEFAULT NULL,
  `EntryText` text,
  `LastUpdatedByAgent_ID` smallint(5) unsigned DEFAULT NULL,
  PRIMARY KEY (`Entry_ID`),
  KEY `TicketNum` (`TicketNum`),
  KEY `EntryDateTime` (`EntryDateTime`),
  KEY `HoursSpent` (`HoursSpent`),
  KEY `Rating` (`Rating`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `tickettagsmap` (
  `TicketNum` int(11) unsigned NOT NULL,
  `Tag_ID` int(10) unsigned NOT NULL,
  `AddedByAgent_ID` smallint(5) unsigned NOT NULL,
  `DateTimeAdded` datetime NOT NULL,
  PRIMARY KEY (`TicketNum`,`Tag_ID`),
  KEY `Tag_ID` (`Tag_ID`),
  KEY `fk_AgentID` (`AddedByAgent_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</code>```

Based on what I've read, the best way to handle this is to create duplicate tables, only with two extra fields per table:

```<code>ModifiedDateTime
Action
</code>```

Is this really the best way? Every time even the slightest change is made to a record, the entire record is inserted into its corresponding history table. It seems like a huge waste of space. Is there a better way to do this?

答:
One simple way to do this is

Enable MySql logging.

Check for updates in the logs.

Enable logging in MySQL:

Type the following in mysql backend console.

```<code>SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';
</code>```

Check for updates with queries: (you can customize this to your need)

```<code>select argument from mysql.general_log where argument REGEXP '*INSERT*';
</code>```

Title: Tracking MySQL Database Changes

Body:
I'm running MySQL 5.1.36 and have a database used for a web-based help desk system. The database has three tables I'd like to track changes for:

CREATE TABLE IF NOT EXISTS `tickets` (
  `TicketNum` int(11) unsigned NOT NULL,
  `SubmittedFromIP` tinyblob,
  `SubmittedFromDevice` varchar(255) DEFAULT NULL,
  `EntryDate` datetime DEFAULT NULL,
  `ClosedDate` datetime DEFAULT NULL,
  `LastName` varchar(50) DEFAULT NULL,
  `FirstName` varchar(50) DEFAULT NULL,
  `Email` varchar(50) DEFAULT NULL,
  `Location` varchar(4) DEFAULT NULL,
  `InventoryNumber` varchar(50) DEFAULT NULL,
  `DeviceName` varchar(50) DEFAULT NULL,
  `Description` text,
  `Notes` text,
  `Agent_ID` smallint(5) unsigned NOT NULL DEFAULT '1',
  `TotalHoursSpent` float NOT NULL DEFAULT '0',
  `Status` smallint(5) unsigned NOT NULL DEFAULT '1',
  `Priority` tinyint(4) NOT NULL DEFAULT '0',
  `LastUpdatedByAgent_ID` smallint(5) unsigned DEFAULT NULL,
  PRIMARY KEY (`TicketNum`),
  KEY `ClosedDate` (`ClosedDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `ticketsolutions` (
  `Entry_ID` int(10) unsigned NOT NULL,
  `TicketNum` mediumint(8) unsigned DEFAULT NULL,
  `EntryDateTime` datetime DEFAULT NULL,
  `HoursSpent` float DEFAULT NULL,
  `Agent_ID` smallint(5) unsigned DEFAULT NULL,
  `EntryText` text,
  `LastUpdatedByAgent_ID` smallint(5) unsigned DEFAULT NULL,
  PRIMARY KEY (`Entry_ID`),
  KEY `TicketNum` (`TicketNum`),
  KEY `EntryDateTime` (`EntryDateTime`),
  KEY `HoursSpent` (`HoursSpent`),
  KEY `Rating` (`Rating`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `tickettagsmap` (
  `TicketNum` int(11) unsigned NOT NULL,
  `Tag_ID` int(10) unsigned NOT NULL,
  `AddedByAgent_ID` smallint(5) unsigned NOT NULL,
  `DateTimeAdded` datetime NOT NULL,
  PRIMARY KEY (`TicketNum`,`Tag_ID`),
  KEY `Tag_ID` (`Tag_ID`),
  KEY `fk_AgentID` (`AddedByAgent_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Based on what I've read, the best way to handle this is to create duplicate tables, only with two extra fields per table:

ModifiedDateTime
Action

Is this really the best way? Every time even the slightest change is made to a record, the entire record is inserted into its corresponding history table. It seems like a huge waste of space. Is there a better way to do this?

Body:
One simple way to do this is

Enable MySql logging.

Check for updates in the logs.

Enable logging in MySQL:

Type the following in mysql backend console.

SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';

Check for updates with queries: (you can customize this to your need)

select argument from mysql.general_log where argument REGEXP '*INSERT*';


问:
do_upload and move_uploaded_file
I'm lapiz new to codeigniter and some functions in php

I'm here to ask again something that's bothering me in uploading files

I tried searching for do_upload vs move_uploaded_file but I didn't get a good response or clear explanation.

What's the difference between "do_upload" from "move_uploaded_file" when it comes in uploading files using php?

I've been using move_uploaded_file mostly since I'm used in programming native PHP, but I saw in a tuts(tutorial)of codeigniter the term "do_upload" this is new to my eyes and ears so maybe someone can explain it briefly?

答:
Actually move_uploaded_file is a core PHP function that helps you to upload files.

And there is Codeigniter's file upload library's method do_upload which also helps you to upload files.

When you are using Codeigniter and you want more than just uploading the file (like you want the file type restrictions, size restriction, maintain uploaded file renaming etc.) with ease then Codigniter's do_upload method (i mean Upload library) will be more handy.

You can see the documentation to know more about Codeigniter's upload library.

https://www.codeigniter.com/user_guide/libraries/file_uploading.html#the-controller

Title: do_upload and move_uploaded_file