问:
"Error: SignerSign() failed." (-2147023673/0x800704c7)
While using signtool for code signing on our buildserver jenkins shows the following error message:

```<code>Done Adding Additional Store
Error information: "Error: SignerSign() failed." (-2147023673/0x800704c7)
SignTool Error: An unexpected internal error has occurred.
</code>```

We use an EV code sign certificate on a USB token. All tools are the latest ones available actually.

Any ideas?

It is not a problem at all using the same build task and running it manually on the same machine (as the user mentioned below) that jenkins is running on, and the same environment / directory.

The Jenkins service runs on a Windows 10 pro VM as a simple user with admin rights (not as Local System).

For more details see this excerpt from the Jenkins log:

```<code>  Signiere FlinkySchule.FormularEditor.exe:
  Verbindung zu Token auf- bzw. abbauen
  ***** code signing *****
  Aktueller Pfad des signtool:
  c:\JW\FS\Production\Deployment\Tools\signtool\kits
  Zu signierende Datei:
  c:\JW\FS\Production\Application\Assemblies\FlinkySchule.FormularEditor\bin\Release\\FlinkySchule.FormularEditor.exe
  The following certificate was selected:
      Issued to: Dirk W.

      Issued by: GlobalSign CodeSigning CA - SHA256 - G3

      Expires:   Fri Apr 03 15:58:51 2020

      SHA1 hash: 4187Cxyxyxyxyxyxyxyxyxyxyx7978C4

  Done Adding Additional Store
EXEC : error information: "Error: SignerSign() failed." (2147023673/0x800704c7) [c:\JW\FS\Production\Application\Assemblies\FlinkySchule.FormularEditor\FlinkySchule.FormularEditor.csproj]
EXEC : SignTool error : An unexpected internal error has occurred. [c:\JW\FS\Production\Application\Assemblies\FlinkySchule.FormularEditor\FlinkySchule.FormularEditor.csproj]
</code>```

One issue was the over all path length:
Even in the year 2017 you will run into the 260 characters path length restriction. Annoying! But we solved this and the error still occurs sometimes.

答:
I ran into this problem as well. I was able to duplicate error outside of Jenkins by running Signtool.exe, but when the prompt appeared for the token password, click cancel. You'll get the same error.

I have a C program which watches for the Symantec prompt and automatically enters the toke password. But Jenkins clearly wasn't running Signtool.exe in the same context as my password helper program. So I then edited my program which runs Signtool.exe to run the password helper program as well. It was still no good. Then I realized that maybe the problem how Jenkins is being run on the node. I had the Jenkins node running a service. Once I stopped the service, and connected by running the java command directly on the command line, it worked!

So now I know, if I'm going to run signtool on a Windows node, make sure the node is connected by running on the command line (via scheduled task), not a service. This changes the context Jenkins is run under which allows SignTool and the Token Prompt to play nice.

ContentLicense: CC BY-SA 4.0

Body:
While using signtool for code signing on our buildserver jenkins shows the following error message:

Done Adding Additional Store
Error information: "Error: SignerSign() failed." (-2147023673/0x800704c7)
SignTool Error: An unexpected internal error has occurred.

We use an EV code sign certificate on a USB token. All tools are the latest ones available actually.

Any ideas?

It is not a problem at all using the same build task and running it manually on the same machine (as the user mentioned below) that jenkins is running on, and the same environment / directory.

The Jenkins service runs on a Windows 10 pro VM as a simple user with admin rights (not as Local System).

For more details see this excerpt from the Jenkins log:

  Signiere FlinkySchule.FormularEditor.exe:
  Verbindung zu Token auf- bzw. abbauen
  ***** code signing *****
  Aktueller Pfad des signtool:
  c:\JW\FS\Production\Deployment\Tools\signtool\kits
  Zu signierende Datei:
  c:\JW\FS\Production\Application\Assemblies\FlinkySchule.FormularEditor\bin\Release\\FlinkySchule.FormularEditor.exe
  The following certificate was selected:
      Issued to: Dirk W.

      Issued by: GlobalSign CodeSigning CA - SHA256 - G3

      Expires:   Fri Apr 03 15:58:51 2020

      SHA1 hash: 4187Cxyxyxyxyxyxyxyxyxyxyx7978C4

  Done Adding Additional Store
EXEC : error information: "Error: SignerSign() failed." (2147023673/0x800704c7) [c:\JW\FS\Production\Application\Assemblies\FlinkySchule.FormularEditor\FlinkySchule.FormularEditor.csproj]
EXEC : SignTool error : An unexpected internal error has occurred. [c:\JW\FS\Production\Application\Assemblies\FlinkySchule.FormularEditor\FlinkySchule.FormularEditor.csproj]

One issue was the over all path length:
Even in the year 2017 you will run into the 260 characters path length restriction. Annoying! But we solved this and the error still occurs sometimes.


来源: stackexchange

问:
Throwing out top and bottom N data points in R
I am new to R and I have tried searching for an answer. I read about quantile and the "partial" argument of sort, but my apologies if I am missing something obvious. I'm wondering if there is a way of doing the following:

Take an unsorted data set and sort it on x

Throw away the top N data points

Throw away the bottom N data points

Perform a regression

Like for example, if i have 400 data points, I might want to throw away the top 5 and bottom 5 data points (not throw away values that are top 5% etc like I believe quantile would be).

Here's the code I have so far for performing the regression (some of the "if"-statements get a little complicated, so I left most of them out to try to simplify things):

Everything is in the dataframe "dependencies."

```<code>myY <- dependencies$yValue
myX0 <- dependencies$xValue
if ( timeInterval == 0 ) {
  cat("A","\n")
  myY <- dependencies$yValueAlternate
} else if ( timeInterval == 1 ) {
  myX1 <- dependencies$xValueAlternate
}

##Add truncation step

if ( timeInterval == 0 ){
  myLm <- lm(myY~myX0,dependencies)
} else if ( timeInterval == 1){
  myLm <- lm(myY~myX0+myX1,dependencies)
}
print(myLm)
intercept <- coef(myLm)["(Intercept)"]
beta1 <- coef(myLm)["myX0"]
</code>```

Thanks for reading and any advice/direction you can give.

答:
If you are deliberately pulling data from the data frame this may be helpful. The parentheses within the brackets are important.</p>

```<code>x <- sample(1:10000, 500, replace = TRUE)
n <- 5
z <- x[(1+n) : (length(x) - n)]
length(z)
[1] 490
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am new to R and I have tried searching for an answer. I read about quantile and the "partial" argument of sort, but my apologies if I am missing something obvious. I'm wondering if there is a way of doing the following:

Take an unsorted data set and sort it on x

Throw away the top N data points

Throw away the bottom N data points

Perform a regression

Like for example, if i have 400 data points, I might want to throw away the top 5 and bottom 5 data points (not throw away values that are top 5% etc like I believe quantile would be).

Here's the code I have so far for performing the regression (some of the "if"-statements get a little complicated, so I left most of them out to try to simplify things):

Everything is in the dataframe "dependencies."

myY <- dependencies$yValue
myX0 <- dependencies$xValue
if ( timeInterval == 0 ) {
  cat("A","\n")
  myY <- dependencies$yValueAlternate
} else if ( timeInterval == 1 ) {
  myX1 <- dependencies$xValueAlternate
}

##Add truncation step

if ( timeInterval == 0 ){
  myLm <- lm(myY~myX0,dependencies)
} else if ( timeInterval == 1){
  myLm <- lm(myY~myX0+myX1,dependencies)
}
print(myLm)
intercept <- coef(myLm)["(Intercept)"]
beta1 <- coef(myLm)["myX0"]

Thanks for reading and any advice/direction you can give.

Body:
If you are deliberately pulling data from the data frame this may be helpful. The parentheses within the brackets are important.

x <- sample(1:10000, 500, replace = TRUE)
n <- 5
z <- x[(1+n) : (length(x) - n)]
length(z)
[1] 490


问:
CodeIgniter Tank Auth
I am making use of this excellent library called Tank Auth. Hopefully this question won't be too niche as its specific to this library.

I am trying to work how I can login a user as soon as they have registered. It seems this library doesn't offer this functionality and I don't want to start messing with the library but maybe someone has done this already and can describe a non-hackey way of getting this to work?

Thanks all for any help.

答:
The creator of this email library was kind enough to reply to my email very quickly and it was a very easy solution! As simple as calling the login function!</p>

```<code>$this->tank_auth->login($data['email'], $this->form_validation->set_value('password'), true, $data['login_by_username'], $data['login_by_email']);
</code>```

ContentLicense: CC BY-SA 2.5

Title: CodeIgniter Tank Auth

Body:
The creator of this email library was kind enough to reply to my email very quickly and it was a very easy solution! As simple as calling the login function!

$this->tank_auth->login($data['email'], $this->form_validation->set_value('password'), true, $data['login_by_username'], $data['login_by_email']);


问:
Error "database compatibility level is not supported." while import MSSQL db
I try to import db schema (MSSQL2008) by Visual Studio 2015 using SqlProj. There are two database to do.

DevDb ver. 10.50.4000 <- I log with Windows Credentials

TestDb ver. 10.50.6000 <- I log with sql's user

Compability level 100 for both dbs is "100".

For first everything goes fine, but for second db error occurs.

"The server version or database compatibility level is not supported."

There is no logs, any entry in EventLog. Mayby I should install something plugin for VisualStudio to handle litter newer version?

答:
Just ran into this one myself importing a 2008 database into VS 2017.

To start, make sure the project is set for the database version you're using.

Go to Project -> Properties ...

Pick the correct Target Platform

Hit Database Settings, and go to Miscellaneous

Verify your Compatibility level

Save these changes (Control + S)

Then - CLOSE THE PROJECT. I closed VS completely

Open everything back up.

Your changes should have taken effect, allowing you to import the database.


问:
Creating multiple tables with a macro
I have a workbook in which each worksheet has identically formatted data but for different entities. I'd like to make each of these in to a table, but I'm unfamiliar with how to write anything like this. There's too many sheets to make doing this by hand an efficient option. Below is my attempt at coding this but it's pretty broken. Again, I've never actually tried to do anything like this. </p>

<p>My intention is that I would have this workbook open, I'd run the macro, and it would loop through each sheet and create a table for the present data. Then I would play around with the pivot table I'd use these table for. Can anyone offer some help, please? </p>

```<code>Sub Create_Tables()

    Dim wrksht As Worksheet

    For Each sht In ActiveWorkbook.Worksheets

        With ActiveSheet
           .ListObjects.Add(xlSrnRange, Range("AE1", Range ("AE1").End(xlToRight).End(xlDown)) , , xlYes)
           .Name:= .Name & "_Table"

           .ListObjects(.Name & "_Table").TableStyle = "TableStyleLight1"

    Next sht

End Sub
</code>```

答:
This tested code will work. Hopefully you can discern the slight modifications I have made.</p>

```<code>Option Explicit

Sub Create_Tables()

    Dim wrksht As Worksheet

    For Each wrksht In ThisWorkbook.Worksheets

        With wrksht

            Dim myTable As ListObject

            Set myTable = .ListObjects.Add(xlSrcRange, wrksht.Range("AE1", wrksht.Range("AE1").End(xlToRight).End(xlDown)), , xlYes)

            With myTable
                .Name = .Name & "_Table"
                .TableStyle = "TableStyleLight1"
            End With

        End With

    Next wrksht

End Sub
</code>```

Title: Creating multiple tables with a macro

Body:
I have a workbook in which each worksheet has identically formatted data but for different entities. I'd like to make each of these in to a table, but I'm unfamiliar with how to write anything like this. There's too many sheets to make doing this by hand an efficient option. Below is my attempt at coding this but it's pretty broken. Again, I've never actually tried to do anything like this.

My intention is that I would have this workbook open, I'd run the macro, and it would loop through each sheet and create a table for the present data. Then I would play around with the pivot table I'd use these table for. Can anyone offer some help, please?

Sub Create_Tables()

    Dim wrksht As Worksheet

    For Each sht In ActiveWorkbook.Worksheets

        With ActiveSheet
           .ListObjects.Add(xlSrnRange, Range("AE1", Range ("AE1").End(xlToRight).End(xlDown)) , , xlYes)
           .Name:= .Name & "_Table"

           .ListObjects(.Name & "_Table").TableStyle = "TableStyleLight1"

    Next sht

End Sub

Body:
This tested code will work. Hopefully you can discern the slight modifications I have made.

Option Explicit

Sub Create_Tables()

    Dim wrksht As Worksheet

    For Each wrksht In ThisWorkbook.Worksheets

        With wrksht

            Dim myTable As ListObject

            Set myTable = .ListObjects.Add(xlSrcRange, wrksht.Range("AE1", wrksht.Range("AE1").End(xlToRight).End(xlDown)), , xlYes)

            With myTable
                .Name = .Name & "_Table"
                .TableStyle = "TableStyleLight1"
            End With

        End With

    Next wrksht

End Sub


问:
Trouble with init branch.io
I use branch.io for work with app link. AndroidManifest has intent-filter for Branch URI scheme:

```<code><intent-filter>
    <data android:scheme="***" android:host="open" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</code>```

Also AndroidManifest has intent-filter for App Links:

```<code><intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" android:host="***.app.link" />
            <data
                android:host="***-alternate.app.link"
                android:scheme="https"/>
            <data
                android:host="***.test-app.link"
                android:scheme="https"/>
            <data
                android:host="***-alternate.test-app.link"
                android:scheme="https"/>
</code>```

LaunchMode for AppLinkActivity is singleTask. I init Branch in Application, in onCreate:

```<code>Branch.getAutoInstance(this);
</code>```

After open AppLinkActivity I get instance and I init session:

```<code>Branch branch = Branch.getInstance(getApplicationContext());
   branch.initSession((referringParams, error) -> {
        LogFileUtil.writeLog("Finish init session");
        if (error == null) {
            //Кое что делаю
        } else {
           //Кое что делаю
        }
    }, this.getIntent().getData(), this);
</code>```

When I open my app across AppLink referringParams isn't empty. And I can get required data.
But when app is open and I click AppLink from other app, that referringParams is empty. I think the problem is init Branch. How I can fix it?

答:
You need to make sure that you override the onNewIntent() method in your AppLinkActivity. This will ensure that the same intent is returned.

Add the following snippet to your AppLinkActivity:

```<code>@Override
protected void onNewIntent(Intent intent) {
    this.setIntent(intent);
}
</code>```

Title: Trouble with init branch.io

Body:
I use branch.io for work with app link. AndroidManifest has intent-filter for Branch URI scheme:

<intent-filter>
    <data android:scheme="***" android:host="open" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

Also AndroidManifest has intent-filter for App Links:

<intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" android:host="***.app.link" />
            <data
                android:host="***-alternate.app.link"
                android:scheme="https"/>
            <data
                android:host="***.test-app.link"
                android:scheme="https"/>
            <data
                android:host="***-alternate.test-app.link"
                android:scheme="https"/>

LaunchMode for AppLinkActivity is singleTask. I init Branch in Application, in onCreate:

Branch.getAutoInstance(this);

After open AppLinkActivity I get instance and I init session:

Branch branch = Branch.getInstance(getApplicationContext());
   branch.initSession((referringParams, error) -> {
        LogFileUtil.writeLog("Finish init session");
        if (error == null) {
            //Кое что делаю
        } else {
           //Кое что делаю
        }
    }, this.getIntent().getData(), this);

When I open my app across AppLink referringParams isn't empty. And I can get required data.
But when app is open and I click AppLink from other app, that referringParams is empty. I think the problem is init Branch. How I can fix it?

Body:
You need to make sure that you override the onNewIntent() method in your AppLinkActivity. This will ensure that the same intent is returned.

Add the following snippet to your AppLinkActivity:

@Override
protected void onNewIntent(Intent intent) {
    this.setIntent(intent);
}


问:
What is the correct way to share the result of an Angular Http network call in RxJs 5?
By using Http, we call a method that does a network call and returns an http observable:

getCustomer() {
    return this.http.get('/someUrl').map(res => res.json());
}
```

<p>If we take this observable and add multiple subscribers to it:</p>

<pre class="lang-js prettyprint-override"><code>let network$ = getCustomer();

let subscriber1 = network$.subscribe(...);
let subscriber2 = network$.subscribe(...);
</code>```

What we want to do, is ensure that this does not cause multiple network requests.

This might seem like an unusual scenario, but its actually quite common: for example if the caller subscribes to the observable to display an error message, and passes it to the template using the async pipe, we already have two subscribers.

What is the correct way of doing that in RxJs 5?

Namely, this seems to work fine:

getCustomer() {
    return this.http.get('/someUrl').map(res => res.json()).share();
}
```

But is this the idiomatic way of doing this in RxJs 5, or should we do something else instead?

Note : As per Angular 5 new HttpClient, the .map(res => res.json()) part in all examples is now useless, as JSON result is now assumed by default.

答:
It's .publishReplay(1).refCount(); or .publishLast().refCount(); since Angular Http observables complete after request.

This simple class caches the result so you can subscribe to .value many times and makes only 1 request. You can also use .reload() to make new request and publish data.

You can use it like:

```<code>let res = new RestResource(() => this.http.get('inline.bundleo.js'));

res.status.subscribe((loading)=>{
    console.log('STATUS=',loading);
});

res.value.subscribe((value) => {
  console.log('VALUE=', value);
});
</code>```

and the source:

```<code>export class RestResource {

  static readonly LOADING: string = 'RestResource_Loading';
  static readonly ERROR: string = 'RestResource_Error';
  static readonly IDLE: string = 'RestResource_Idle';

  public value: Observable<any>;
  public status: Observable<string>;
  private loadStatus: Observer<any>;

  private reloader: Observable<any>;
  private reloadTrigger: Observer<any>;

  constructor(requestObservableFn: () => Observable<any>) {
    this.status = Observable.create((o) => {
      this.loadStatus = o;
    });

    this.reloader = Observable.create((o: Observer<any>) => {
      this.reloadTrigger = o;
    });

    this.value = this.reloader.startWith(null).switchMap(() => {
      if (this.loadStatus) {
        this.loadStatus.next(RestResource.LOADING);
      }
      return requestObservableFn()
        .map((res) => {
          if (this.loadStatus) {
            this.loadStatus.next(RestResource.IDLE);
          }
          return res;
        }).catch((err)=>{
          if (this.loadStatus) {
            this.loadStatus.next(RestResource.ERROR);
          }
          return Observable.of(null);
        });
    }).publishReplay(1).refCount();
  }

  reload() {
    this.reloadTrigger.next(null);
  }

}
</code>```

Body:
By using Http, we call a method that does a network call and returns an http observable:

getCustomer() {
    return this.http.get('/someUrl').map(res => res.json());
}

If we take this observable and add multiple subscribers to it:

let network$ = getCustomer();

let subscriber1 = network$.subscribe(...);
let subscriber2 = network$.subscribe(...);

What we want to do, is ensure that this does not cause multiple network requests.

This might seem like an unusual scenario, but its actually quite common: for example if the caller subscribes to the observable to display an error message, and passes it to the template using the async pipe, we already have two subscribers.

What is the correct way of doing that in RxJs 5?

Namely, this seems to work fine:

getCustomer() {
    return this.http.get('/someUrl').map(res => res.json()).share();
}

But is this the idiomatic way of doing this in RxJs 5, or should we do something else instead?

Note : As per Angular 5 new HttpClient, the .map(res => res.json()) part in all examples is now useless, as JSON result is now assumed by default.

Body:
It's .publishReplay(1).refCount(); or .publishLast().refCount(); since Angular Http observables complete after request.

This simple class caches the result so you can subscribe to .value many times and makes only 1 request. You can also use .reload() to make new request and publish data.

You can use it like:

let res = new RestResource(() => this.http.get('inline.bundleo.js'));

res.status.subscribe((loading)=>{
    console.log('STATUS=',loading);
});

res.value.subscribe((value) => {
  console.log('VALUE=', value);
});

and the source:

export class RestResource {

  static readonly LOADING: string = 'RestResource_Loading';
  static readonly ERROR: string = 'RestResource_Error';
  static readonly IDLE: string = 'RestResource_Idle';

  public value: Observable<any>;
  public status: Observable<string>;
  private loadStatus: Observer<any>;

  private reloader: Observable<any>;
  private reloadTrigger: Observer<any>;

  constructor(requestObservableFn: () => Observable<any>) {
    this.status = Observable.create((o) => {
      this.loadStatus = o;
    });

    this.reloader = Observable.create((o: Observer<any>) => {
      this.reloadTrigger = o;
    });

    this.value = this.reloader.startWith(null).switchMap(() => {
      if (this.loadStatus) {
        this.loadStatus.next(RestResource.LOADING);
      }
      return requestObservableFn()
        .map((res) => {
          if (this.loadStatus) {
            this.loadStatus.next(RestResource.IDLE);
          }
          return res;
        }).catch((err)=>{
          if (this.loadStatus) {
            this.loadStatus.next(RestResource.ERROR);
          }
          return Observable.of(null);
        });
    }).publishReplay(1).refCount();
  }

  reload() {
    this.reloadTrigger.next(null);
  }

}


问:
How to check if an Array of strings is sorted in alphabetical order or not using Kotlin?
I am given a list of strings and I need to see if they are in alphabetical order.

I know I need to use a for loop and check the first character of each string but I don't know how to progress from there.

```<code>for (item in array)
     println(item[0])
</code>```

For example ["adam", "ben", "chloe"] should return true.

And likewise for ["ben", "adam", "chloe"] should return false.

答:
Im sure you could do your desired task completely using a for-loop.

However in Kotlin I personally think it would be more idiomatic to do something like this using until:

```<code>fun isAlphabetical(stringsArray: Array<String>): Boolean {
    if (stringsArray.size < 2) return true
    return (1 until stringsArray.size).none { stringsArray[it] <= stringsArray[it - 1] }
}

fun main(args: Array<String>) {
    val testCases = arrayOf(arrayOf("adam", "ben", "chloe"), arrayOf("ben", "adam", "chloe"))

    for(testCase : Array<String> in testCases){
        println("The strings are: ${testCase.joinToString()}")
        if (isAlphabetical(testCase)) {
            println("Strings are in alphabetical order.\n")
        } else {
            println("Strings are not in alphabetical order.\n")
        }
    }
}
</code>```

Output:

```<code>The strings are: adam, ben, chloe
Strings are in alphabetical order.

The strings are: ben, adam, chloe
Strings are not in alphabetical order.
</code>```

Basically you only compare each element of the array with the previous element (using <=) if the length of the array is more than 1.

Body:
I am given a list of strings and I need to see if they are in alphabetical order.

I know I need to use a for loop and check the first character of each string but I don't know how to progress from there.

for (item in array)
     println(item[0])

For example ["adam", "ben", "chloe"] should return true.

And likewise for ["ben", "adam", "chloe"] should return false.

Body:
Im sure you could do your desired task completely using a for-loop.

However in Kotlin I personally think it would be more idiomatic to do something like this using until:

fun isAlphabetical(stringsArray: Array<String>): Boolean {
    if (stringsArray.size < 2) return true
    return (1 until stringsArray.size).none { stringsArray[it] <= stringsArray[it - 1] }
}

fun main(args: Array<String>) {
    val testCases = arrayOf(arrayOf("adam", "ben", "chloe"), arrayOf("ben", "adam", "chloe"))

    for(testCase : Array<String> in testCases){
        println("The strings are: ${testCase.joinToString()}")
        if (isAlphabetical(testCase)) {
            println("Strings are in alphabetical order.\n")
        } else {
            println("Strings are not in alphabetical order.\n")
        }
    }
}

Output:

The strings are: adam, ben, chloe
Strings are in alphabetical order.

The strings are: ben, adam, chloe
Strings are not in alphabetical order.

Basically you only compare each element of the array with the previous element (using <=) if the length of the array is more than 1.


问:
Can I make a custom matcher for Flutter unit or integration tests?
I'm writing a unit or integration test for mobile. Can I make a custom matcher?</p>

答:
Yes, you can create custom Matcher classes and custom Finder classes.

Here's one of Flutter's custom matchers that asserts that the given Finder finds a widget that's inside a Card widget:

```<code>class _IsInCard extends Matcher {
  const _IsInCard();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) => _hasAncestorOfType(finder, Card);

  @override
  Description describe(Description description) => description.add('in card');
}
</code>```

The Matcher class is not part of the Flutter framework. It is defined in package:mathcer. Flutter inherits it from package:test. All Flutter's own Matcher classes are custom implementations of it.

Flutter's test framework has lots of custom matchers and custom finders you can learn from.

Body:
Yes, you can create custom Matcher classes and custom Finder classes.

Here's one of Flutter's custom matchers that asserts that the given Finder finds a widget that's inside a Card widget:

class _IsInCard extends Matcher {
  const _IsInCard();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) => _hasAncestorOfType(finder, Card);

  @override
  Description describe(Description description) => description.add('in card');
}

The Matcher class is not part of the Flutter framework. It is defined in package:mathcer. Flutter inherits it from package:test. All Flutter's own Matcher classes are custom implementations of it.

Flutter's test framework has lots of custom matchers and custom finders you can learn from.


问:
Removing carriage return and linefeed from the end of a string in C#
How do I remove the carriage return character (\r) and
the Unix newline character(\n) from the end of a string?

答:
I use lots of erasing level

```<code>String donen = "lots of stupid whitespaces and new lines and others..."

//Remove multilines
donen = Regex.Replace(donen, @"^\s+$[\r\n]*", "", RegexOptions.Multiline);
//remove multi whitespaces
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
donen = regex.Replace(donen, " ");
//remove tabs
char tab = '\u0009';
donen = donen.Replace(tab.ToString(), "");
//remove endoffile newlines
donen = donen.TrimEnd('\r', '\n');
//to be sure erase new lines again from another perspective
donen.Replace(Environment.NewLine, "");
</code>```

and now we have a clean one row

Body:
I use lots of erasing level

String donen = "lots of stupid whitespaces and new lines and others..."

//Remove multilines
donen = Regex.Replace(donen, @"^\s+$[\r\n]*", "", RegexOptions.Multiline);
//remove multi whitespaces
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
donen = regex.Replace(donen, " ");
//remove tabs
char tab = '\u0009';
donen = donen.Replace(tab.ToString(), "");
//remove endoffile newlines
donen = donen.TrimEnd('\r', '\n');
//to be sure erase new lines again from another perspective
donen.Replace(Environment.NewLine, "");

and now we have a clean one row


问:
App Store Guidelines in-app purchase
I am developing an app for an author who wrote a book helping people to communicate better. The book contains some exercises. The author wants an app, with which the customer can do these exercises on the go.

The author wants:

A trial version with limited amount of exercises

A possibility to buy all exercises using in-app purchase

Customers who bought the book should be able to unlock all exercises without paying.

This is easy to do on a technical level, however does anyone have some experience if apple allows an app with such behaviour? The apple guidelines say:

3.1.4 Content Codes: Apps may not use their own mechanisms to unlock content or functionality, such as license keys, augmented reality markers, QR codes, etc. In limited circumstances, such as when features are dependent upon specific hardware to function, the app may unlock that functionality without using in-app purchase (e.g. an astronomy app that adds features when synced with a telescope). App features that work in combination with an approved physical product (such as a toy) on an optional basis may unlock functionality without using IAP, provided that an IAP option is available as well. You may not, however, require users to purchase unrelated products or engage in advertising or marketing activities to unlock app functionality.

I am not sure how to interpret them in case of the book.

答:
I think your fine for this case.

If you provide a way for users to pay in the app and also provide a way to get that same content for free you should be fine. Buying the product is optional. You can unlock by paying in app, or buying the product.

I think that is what they mean by:

App features that work in combination with an approved physical
  product (such as a toy) on an optional basis may unlock functionality
  without using IAP, provided that an IAP option is available as well.

Title: App Store Guidelines in-app purchase


问:
Show system messages in conversation history using iOS Twilio SDK
Hi I have been working on one of my apps for integrating chat using Twilio SDK. I would want to know if it is possible to get the system message inside a channel for eg: 'Member A joined the channel', 'Member B left the channel', 'Member C accepted the invitation to join' and so on. It seems like Twilio SDK does not have API to get the system messages or to set them. How can we achieve this?

I also noticed that it can be achieved by setting the custom key-value pair in attributes inside the message and sending it to the channel. But for the newly invited members, they cannot send a message when they are declining the invitation request such as 'Member A declined the invitation to join channel', as they have not joined the channel yet.

答:
Twilio developer evangelist here.

If you want to send persistent system level messages like this, you can do so with a combination of webhooks and the REST API.

The idea is that you can send messages to a channel using the REST API whenever you need one of these system messages. The default user for the REST API is the system and you can then treat messages from system as special for display in your UI.

I mention the webhooks because you can register to receive them for a number of useful events, like members joining and leaving channels. The webhooks may not cover all the things you want, like declining an invite, but for that I would just trigger my own HTTP request from the application to your server.

Let me know if that helps at all.


问:
How to get user ID (FOSUserBundle) in form builder in Symfony2?
I'm quite new here, be patient, please.

I'm trying to make notice board project in Symfony2 using FOSUserBundle.
I try to get logged user id to put it into form created with form builder (and then to MySQL database).
One of attempts  is:

```<code>public function createNoticeAction(Request $request)
    {
        $notice = new Notice();
        $form = $this->createFormBuilder($notice)
            ->add("content", "text")
            ->add("user_id","entity",
                array("class"=>"FOS/UserBundle/FOSUserBundle:", "choice_label"=>"id"))
            ->add("isActive", "true")
            ->add("category", "entity",
                array("class" => "AppBundle:Category", "choice_label" => "name"))
            ->add("save", "submit", array("label" => "Save"))
            ->getForm();
        $form->handleRequest($request);
        $em = $this->getDoctrine()->getManager();
        $em->persist($notice);
        $em->flush();

        return $this->redirectToRoute('app_user_showuserpage');
    }
</code>```

I tried many solutions again and again and  I get some error.

答:
for symfony 3.2.13

have excelent solution (just because is working, but is dangerous if someone discover it in pure HTML)

1) first build YourFormType class.

add normal field in Forms/YourFormType.php (if not, formbuilder tell you that you passing smth not quite right (too many fields) ; -) )

```<code>$builder
            ->add(
                'MyModelAddedById',
                HiddenType::class,
                [
                'label' => 'echhh', //somehow it has to be here
                'attr' => ['style' => 'display:none'], //somehow it has to be here
                ]
    );
</code>```

2) in your controller

```<code>public function addSomethingAction(Request $request){

$form = $this->createForm(MyModelFormType::class);

//set field value
$request->request->set("prodModelAddedById", $this->getUser()->getId());

$form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $product = $form->getData();
            $em = $this->getDoctrine()->getManager();
            $em->persist($product);

            $em->flush();

            $this->addFlash('success', 'record was added');

            return $this->redirectToRoute('products');
        }

        return $this->render(
            'default.add.form.html.twig',
            [
                'newprod' => $form->createView(),
            ]
        );
    }
</code>```

explenation:

you are passing a field and variable to formbuilder (settig it already to default value!)

and important thing, becose of BUG in my opinion - you can't in your form type set method:

```<code>public function getBlockPrefix()
{
    //return 'app_bundle_my_form_type';
}

because
$request->request->set
</code>```

can't work properly if your POST data from form are in bag (parameterbag)

no entity managers, no services, no listeners...

hope it helps.

Body:
I'm quite new here, be patient, please.

I'm trying to make notice board project in Symfony2 using FOSUserBundle.
I try to get logged user id to put it into form created with form builder (and then to MySQL database).
One of attempts  is:

public function createNoticeAction(Request $request)
    {
        $notice = new Notice();
        $form = $this->createFormBuilder($notice)
            ->add("content", "text")
            ->add("user_id","entity",
                array("class"=>"FOS/UserBundle/FOSUserBundle:", "choice_label"=>"id"))
            ->add("isActive", "true")
            ->add("category", "entity",
                array("class" => "AppBundle:Category", "choice_label" => "name"))
            ->add("save", "submit", array("label" => "Save"))
            ->getForm();
        $form->handleRequest($request);
        $em = $this->getDoctrine()->getManager();
        $em->persist($notice);
        $em->flush();

        return $this->redirectToRoute('app_user_showuserpage');
    }

I tried many solutions again and again and  I get some error.

Body:
for symfony 3.2.13

have excelent solution (just because is working, but is dangerous if someone discover it in pure HTML)

1) first build YourFormType class.

add normal field in Forms/YourFormType.php (if not, formbuilder tell you that you passing smth not quite right (too many fields) ; -) )

$builder
            ->add(
                'MyModelAddedById',
                HiddenType::class,
                [
                'label' => 'echhh', //somehow it has to be here
                'attr' => ['style' => 'display:none'], //somehow it has to be here
                ]
    );

2) in your controller

public function addSomethingAction(Request $request){

$form = $this->createForm(MyModelFormType::class);

//set field value
$request->request->set("prodModelAddedById", $this->getUser()->getId());

$form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $product = $form->getData();
            $em = $this->getDoctrine()->getManager();
            $em->persist($product);

            $em->flush();

            $this->addFlash('success', 'record was added');

            return $this->redirectToRoute('products');
        }

        return $this->render(
            'default.add.form.html.twig',
            [
                'newprod' => $form->createView(),
            ]
        );
    }

explenation:

you are passing a field and variable to formbuilder (settig it already to default value!)

and important thing, becose of BUG in my opinion - you can't in your form type set method:

public function getBlockPrefix()
{
    //return 'app_bundle_my_form_type';
}

because
$request->request->set

can't work properly if your POST data from form are in bag (parameterbag)

no entity managers, no services, no listeners...

hope it helps.


问:
Child DIV that floats over the text in the parent DIV
I have a parent  with text in it. Inside the parent, I want to float a child  right, but also OVER the top of the text in the parent. Like this:

答:
Something like this?

.wrapper {
  position: relative;
  display: inline-block;
  padding: 10px;
}

.overlay {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  background: red;
  opacity: 0.5;
  width: 35px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="wrapper">
  Some Random Sample Text Here<div class="overlay"></div>
</div></code>```

Body:
Something like this?

.wrapper {
  position: relative;
  display: inline-block;
  padding: 10px;
}

.overlay {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  background: red;
  opacity: 0.5;
  width: 35px;
}

<div class="wrapper">
  Some Random Sample Text Here<div class="overlay"></div>
</div>


问:
DllNotFoundException: gpg
a friend and I are developing a game in Unity for Android, and we want to include some leaderboards with the Google Play Games Services, but we can't get the login to work.

We are using for the login the script MainGui from the minimal sample project of the Google Play Games Plugin. When we press the authenticate button it keeps saying "authenticating":

```<code>if (!Social.localUser.authenticated)
        {
            // Authenticate
            mWaitingForAuth = true;
            mStatusText = "Authenticating...";
            Social.localUser.Authenticate((bool success) =>
            {
                mWaitingForAuth = false;
                if (success)
                {
                    mStatusText = "Welcome " + Social.localUser.userName;
                }
                else
                {
                    mStatusText = "Authentication failed.";
                }
            });
        }
</code>```

Looking in the logcat, there is an error:

```<code>E/Unity: DllNotFoundException: gpg
at (wrapper managed-to-native) GooglePlayGames.Native.Cwrapper.Builder:GameServices_Builder_Construct ()
at GooglePlayGames.Native.PInvoke.GameServicesBuilder.Create () [0x00000] in <filename unknown>:0
at GooglePlayGames.Native.NativeClient.InitializeGameServices () [0x00000] in <filename unknown>:0
at GooglePlayGames.Native.NativeClient.Authenticate (System.Action`2 callback, Boolean silent) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesPlatform.Authenticate (System.Action`2 callback, Boolean silent) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesPlatform.Authenticate (System.Action`1 callback, Boolean silent) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesPlatform.Authenticate (System.Action`1 callback) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesLocalUser.Authenticate (System.Action`1 callback) [0x00000] in <filename unknown>:0
at LogInAndroid.OnGUI () [0x00000] in <filename unknown>:0
</code>```

We have been searching for hours and tried other answers as well as removed and re-added the plugin to the project, checked the api keys, built from a different computer, etc.

答:
A similar issue is raised and marked closed in the play-games-for-unity-repo by playService : https://github.com/playgameservices/play-games-plugin-for-unity/issues/287

The solution to it that has worked for a few people can be found here. Check the steps mentioned here?

https://github.com/playgameservices/play-games-plugin-for-unity/issues/280#issuecomment-64280552

Title: DllNotFoundException: gpg

Body:
a friend and I are developing a game in Unity for Android, and we want to include some leaderboards with the Google Play Games Services, but we can't get the login to work.

We are using for the login the script MainGui from the minimal sample project of the Google Play Games Plugin. When we press the authenticate button it keeps saying "authenticating":

if (!Social.localUser.authenticated)
        {
            // Authenticate
            mWaitingForAuth = true;
            mStatusText = "Authenticating...";
            Social.localUser.Authenticate((bool success) =>
            {
                mWaitingForAuth = false;
                if (success)
                {
                    mStatusText = "Welcome " + Social.localUser.userName;
                }
                else
                {
                    mStatusText = "Authentication failed.";
                }
            });
        }

Looking in the logcat, there is an error:

E/Unity: DllNotFoundException: gpg
at (wrapper managed-to-native) GooglePlayGames.Native.Cwrapper.Builder:GameServices_Builder_Construct ()
at GooglePlayGames.Native.PInvoke.GameServicesBuilder.Create () [0x00000] in <filename unknown>:0
at GooglePlayGames.Native.NativeClient.InitializeGameServices () [0x00000] in <filename unknown>:0
at GooglePlayGames.Native.NativeClient.Authenticate (System.Action`2 callback, Boolean silent) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesPlatform.Authenticate (System.Action`2 callback, Boolean silent) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesPlatform.Authenticate (System.Action`1 callback, Boolean silent) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesPlatform.Authenticate (System.Action`1 callback) [0x00000] in <filename unknown>:0
at GooglePlayGames.PlayGamesLocalUser.Authenticate (System.Action`1 callback) [0x00000] in <filename unknown>:0
at LogInAndroid.OnGUI () [0x00000] in <filename unknown>:0

We have been searching for hours and tried other answers as well as removed and re-added the plugin to the project, checked the api keys, built from a different computer, etc.


问:
Is it possible to diff PowerPoint version-controlled with git?
I have some PowerPoint documents that I keep version-controlled with git. I want to know what differences are between versions of a file. Text is most important, images and formatting not so much (at least not at this point).</p>

答:
I can't speak directly to git as we use Visual Studio + TFS at work. However, a bit of research reveals this should work. What I do on VS is to integrate WinMerge and its plugin which supports a text comparison of MS Office and PDF files. This allows me to do diffs of pptx, docx, pdf, etc. files published to version control.

For git, the way it should work is:

1) Get WinMerge with the xdocdiff plugin: http://freemind.s57.xrea.com/xdocdiffPlugin/en/index.html
2) Integrate WinMerge with git: https://coderwall.com/p/76wmzq/winmerge-as-git-difftool-on-windows

Hopefully this will allow you to see the text-based diffs for your PowerPoint.


问:
Adding a Table of values to a google sheet (python)
```<code>#Write to sheet
subjects = ['Maths', 'Physics', 'Geography', 'Biology',
            'Chemistry', 'ICT', 'Travel and Tourism', 'Computer Science',
            'History', 'LINC', 'Design and Technology', 'Art',
            'English Literature', 'Welsh', 'MFL', 'Music',
            'Business','Applied Science', 'Medical Science', 'Media']
values =[]
import random
random.shuffle(subjects)

chunks = [subjects[x:x+5] for x in range(0, len(subjects), 5)]
I = chunks[0]
c = 0
for element in I:
    temp = str(element)
    print(temp)
    values.append(temp)
    print(values)
body = {
    'values': values,
    'majorDimension':'COLUMNS'

}
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range="Data!A1:D5",
    valueInputOption='USER_ENTERED',body=body).execute()
</code>```

Running this it will basically move some list elements about randomly, then split them into smaller lists so I can add them column by column, my range is currently A1:D5 on the google sheet however I have tried using just A1 and a single list element and I get the same error, for example only having "Geography" appended to the list

My error is as follows:

googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/1DIP0UqEuS8mcEgAiKnFXaSsyqiUq2LXkGa7VmAJS4S8/values/Data%21A1?valueInputOption=USER_ENTERED&alt=json returned "Invalid value at 'data.values[0]' (type.googleapis.com/google.protobuf.ListValue), "English Literature"">

答:
It seems that values is 1 dimensional list. At spreadsheets().values().update(), the list has to be 2 dimensional list. So how about the following modification?

Pattern 1:

If you want to import the 5 values to "A1:A5", you can use this.

From :

```<code>body = {
    'values': values,
    'majorDimension':'COLUMNS'
}
</code>```

To :

```<code>body = {
    'values': [values], # Modified
    'majorDimension':'COLUMNS'
}
</code>```

Pattern 2:

If you want to import the 5 values to "A1:E1", you can use this.

From :

```<code>for element in I:
    temp = str(element)
    print(temp)
    values.append(temp)
    print(values)
body = {
    'values': values,
    'majorDimension':'COLUMNS'
}
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range="Data!A1:D5",
    valueInputOption='USER_ENTERED',body=body).execute()
</code>```

To :

```<code>for element in I:
    temp = str(element)
    print(temp)
    values.append([temp]) # Modified
    print(values)
body = {
    'values': values,
    'majorDimension':'COLUMNS'
}
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range="Data!A1:E1", # Modified
    valueInputOption='USER_ENTERED',body=body).execute()
</code>```

If I misunderstand your question, I'm sorry.

Body:
#Write to sheet
subjects = ['Maths', 'Physics', 'Geography', 'Biology',
            'Chemistry', 'ICT', 'Travel and Tourism', 'Computer Science',
            'History', 'LINC', 'Design and Technology', 'Art',
            'English Literature', 'Welsh', 'MFL', 'Music',
            'Business','Applied Science', 'Medical Science', 'Media']
values =[]
import random
random.shuffle(subjects)

chunks = [subjects[x:x+5] for x in range(0, len(subjects), 5)]
I = chunks[0]
c = 0
for element in I:
    temp = str(element)
    print(temp)
    values.append(temp)
    print(values)
body = {
    'values': values,
    'majorDimension':'COLUMNS'

}
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range="Data!A1:D5",
    valueInputOption='USER_ENTERED',body=body).execute()

Running this it will basically move some list elements about randomly, then split them into smaller lists so I can add them column by column, my range is currently A1:D5 on the google sheet however I have tried using just A1 and a single list element and I get the same error, for example only having "Geography" appended to the list

My error is as follows:

googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/1DIP0UqEuS8mcEgAiKnFXaSsyqiUq2LXkGa7VmAJS4S8/values/Data%21A1?valueInputOption=USER_ENTERED&alt=json returned "Invalid value at 'data.values[0]' (type.googleapis.com/google.protobuf.ListValue), "English Literature"">

Body:
It seems that values is 1 dimensional list. At spreadsheets().values().update(), the list has to be 2 dimensional list. So how about the following modification?

Pattern 1:

If you want to import the 5 values to "A1:A5", you can use this.

From :

body = {
    'values': values,
    'majorDimension':'COLUMNS'
}

To :

body = {
    'values': [values], # Modified
    'majorDimension':'COLUMNS'
}

Pattern 2:

If you want to import the 5 values to "A1:E1", you can use this.

From :

for element in I:
    temp = str(element)
    print(temp)
    values.append(temp)
    print(values)
body = {
    'values': values,
    'majorDimension':'COLUMNS'
}
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range="Data!A1:D5",
    valueInputOption='USER_ENTERED',body=body).execute()

To :

for element in I:
    temp = str(element)
    print(temp)
    values.append([temp]) # Modified
    print(values)
body = {
    'values': values,
    'majorDimension':'COLUMNS'
}
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range="Data!A1:E1", # Modified
    valueInputOption='USER_ENTERED',body=body).execute()

If I misunderstand your question, I'm sorry.


问:
Using try/catch for files in java
I'm having issues with using try-catch blocks in java. I'm writing a method that reads a user input file and prints it out to the console. This is what I have -

```<code>static Scanner input = new Scanner(System.in);

public static String readingFiles(String fileout) {

    boolean find = false;

    while(!find) {
            try {
                File f = new File(input.nextLine());
                Scanner scan = new Scanner(f);
            } catch (FileNotFoundException e) {
                System.out.println("File Not Found.");

            }
    }
    ArrayList<String> list = new ArrayList<String>();

    while (input.hasNext())
    {
        list.add(input.nextLine());
    }

    String output = list.toString();
    return output;

}
</code>```

It just seems like a mess and I have no idea what to do with it at this point. I had it working a few times, in that it would output what the file said but then if I purposefully entered the wrong file name it would loop "file not found" endlessly and I couldn't figure out how to return the loop to the beginning so the user could input a different file name.

Now it just does nothing even when i enter the correct file name, it returns nothing until i press enter again and it'll return file not found.
I call it using this in my main menu method -

```<code>      case 1:
            System.out.println("You chose Read File. Enter your file name: ");
            System.out.println(Question4.readingFiles(input.nextLine()));

            pressEnter();
            break;
</code>```

edit: I now have this, which works but only prints the first line of my file?

```<code>public static String readingFiles(String fileout) {

    boolean find = false;
    String result = "";
    while (!find) {
        try {
            File read = new File(fileout);
            Scanner check = new Scanner(read);
            result = check.nextLine();
            find = true;
            check.close();
        } catch (FileNotFoundException e) {
            System.out.println("File Not Found. Please try again.");
            break;
        }
    }
    return result;
}
</code>```

答:
Check the following code.

```<code>public static void readFiles() throws Exception {
    int i = 1;
    BufferedReader reader = null;
    Scanner input = null;
    boolean fileFound = true;
    while(i <= 5){
        System.out.print("Enter a file name::::");
        input = new Scanner(System.in);
        if(input.hasNextLine()){
            try {
                File f = new File(input.nextLine());
                reader = new BufferedReader(new FileReader(f));
                String str = null;
                while((str = reader.readLine()) != null){
                    System.out.println(str);
                }
            } catch (FileNotFoundException e) {
                System.out.println("File Not Found");
                fileFound = false;
                i++;
                continue;
            } catch (IOException e) {
                System.out.println("IOException");
                i++;
                continue;
            } catch (Exception e) {
                System.out.println("Some Other Exception");
                i++;
                continue;
            } finally{
                if(fileFound)
                    reader.close();
            }
        }

        i++;
    }

}
</code>```

Please note this method will read files 5 times. If you want to change it, you can pass an int parameter to the method and accordingly change the first while condition. Ensure you give complete path of the file with escape characters. For example, if file location is 'C:\abc.txt', you need to input 'C:\\abc.txt'. Else, it will display 'File Not Found' in console.

Title: Using try/catch for files in java

Body:
I'm having issues with using try-catch blocks in java. I'm writing a method that reads a user input file and prints it out to the console. This is what I have -

static Scanner input = new Scanner(System.in);

public static String readingFiles(String fileout) {

    boolean find = false;

    while(!find) {
            try {
                File f = new File(input.nextLine());
                Scanner scan = new Scanner(f);
            } catch (FileNotFoundException e) {
                System.out.println("File Not Found.");

            }
    }
    ArrayList<String> list = new ArrayList<String>();

    while (input.hasNext())
    {
        list.add(input.nextLine());
    }

    String output = list.toString();
    return output;

}

It just seems like a mess and I have no idea what to do with it at this point. I had it working a few times, in that it would output what the file said but then if I purposefully entered the wrong file name it would loop "file not found" endlessly and I couldn't figure out how to return the loop to the beginning so the user could input a different file name.

Now it just does nothing even when i enter the correct file name, it returns nothing until i press enter again and it'll return file not found.
I call it using this in my main menu method -

      case 1:
            System.out.println("You chose Read File. Enter your file name: ");
            System.out.println(Question4.readingFiles(input.nextLine()));

            pressEnter();
            break;

edit: I now have this, which works but only prints the first line of my file?

public static String readingFiles(String fileout) {

    boolean find = false;
    String result = "";
    while (!find) {
        try {
            File read = new File(fileout);
            Scanner check = new Scanner(read);
            result = check.nextLine();
            find = true;
            check.close();
        } catch (FileNotFoundException e) {
            System.out.println("File Not Found. Please try again.");
            break;
        }
    }
    return result;
}

Body:
Check the following code.

public static void readFiles() throws Exception {
    int i = 1;
    BufferedReader reader = null;
    Scanner input = null;
    boolean fileFound = true;
    while(i <= 5){
        System.out.print("Enter a file name::::");
        input = new Scanner(System.in);
        if(input.hasNextLine()){
            try {
                File f = new File(input.nextLine());
                reader = new BufferedReader(new FileReader(f));
                String str = null;
                while((str = reader.readLine()) != null){
                    System.out.println(str);
                }
            } catch (FileNotFoundException e) {
                System.out.println("File Not Found");
                fileFound = false;
                i++;
                continue;
            } catch (IOException e) {
                System.out.println("IOException");
                i++;
                continue;
            } catch (Exception e) {
                System.out.println("Some Other Exception");
                i++;
                continue;
            } finally{
                if(fileFound)
                    reader.close();
            }
        }

        i++;
    }

}

Please note this method will read files 5 times. If you want to change it, you can pass an int parameter to the method and accordingly change the first while condition. Ensure you give complete path of the file with escape characters. For example, if file location is 'C:\abc.txt', you need to input 'C:\\abc.txt'. Else, it will display 'File Not Found' in console.


问:
Visual Studio Code: Git diff over git gutter indicator
In WebStorm (and also Eclipse, Netbeans), when clicking on the git diff indicators in the gutter, a contextual menu shows the previous content, and provides a button to quickly revert the block modifications.

Visual Studio Code also provides added/modified/deleted blocks gutter indicators, this way:

But I didn't find how to quickly see the corresponding diff. I can't believe there's no quick way to see what the gutter indicators refer to.

Did I miss something? Is it an upcoming feature? Or would someone know about an extension that would add that behavior?

答:
It's here!

It appeared in Visual Studio Code 1.18!

They call it Source Control Inline change review. By the way, they also added coloration over the modified files in the file explorer.


问:
net.iamyellow.gcmjs does not with SDK 6.3.0.GA for titanium appcelerator
We migrated to an old version(Ti 5.2.2).GA to a new version(Ti 6.3.0.GA) of titanium Appcelerator.

When we run our app with latest version(Ti 6.3.0.GA) the net.iamyellow.gcmjs (0.2 & 0.3) module not supported.

My app is depends on net.iamyellow.gcmjs module.

Questions

Is there any latest version of net.iamyellow.gcmjs module to support for titanium SDK Version 6.3.0.GA?

If it is not there when will you release the new version of net.iamyellow.gcmjs module?

Is there any push notification module to support for both android and iOS app which are developed through titanium appcelerator?

Please, can please help me out.

Environments:

```<code>Operating System          = Mac OS X

Node.js Version           = 6.10.3

npm Version               = 3.10.10

Titanium CLI Version      = 5.0.14

Titanium SDK Version      = 6.3.0.GA

Axway Appcelerator Studio = 4.10.0
</code>```

答:
Sorry for the late reply, to answer your question, iamyellow is no longer maintained and this has been the case for at least four years if I recall, with TiSDK 6.x there had been a an update on the v8 version which requires a rebuild of all android native modules if I recall correctly.

That being said, this should not be an issue as there already is a great module by the name of ti.goosh

Hope this helps

Body:
We migrated to an old version(Ti 5.2.2).GA to a new version(Ti 6.3.0.GA) of titanium Appcelerator.

When we run our app with latest version(Ti 6.3.0.GA) the net.iamyellow.gcmjs (0.2 & 0.3) module not supported.

My app is depends on net.iamyellow.gcmjs module.

Questions

Is there any latest version of net.iamyellow.gcmjs module to support for titanium SDK Version 6.3.0.GA?

If it is not there when will you release the new version of net.iamyellow.gcmjs module?

Is there any push notification module to support for both android and iOS app which are developed through titanium appcelerator?

Please, can please help me out.

Environments:

Operating System          = Mac OS X

Node.js Version           = 6.10.3

npm Version               = 3.10.10

Titanium CLI Version      = 5.0.14

Titanium SDK Version      = 6.3.0.GA

Axway Appcelerator Studio = 4.10.0


问:
How to parse comma separated line correctly with regex
Trying to parse comma separated line with regex, but getting inconsistent results:

Regex: ([^,]*),?

The actual value is in match group 1 (excludes the comma).

Expected results:

```<code>a,,b  -> 3 matches
a,,b, -> 4 matches
a,,,b -> 4 matches
</code>```

The number of matches is the number of commas + 1.

The problem is the regex matches at the end even if there is no comma, so getting:

```<code>a,,b  -> 4 matches
a,,b, -> 4 matches
</code>```

Both return 4 matches, even though the lines have a different number of values.

Is it possible to fix the regex so the number of matches is the number of values (commas + 1) without correcting the results in code?

答:
Brief

It seems your regex is not matching any characters in some locations and working as a sort of assertion (asserting that no character is matched in your group and not followed by a comma ,, which is perfectly valid according to your regex).

This answer is a fix that allows you to match 1 or more of any non-comma , character, or an assertion for a zero-width match all-the-while asserting the position as being preceded by a comma ,.

The best way to go about this would be to split the string on , using a string function, but this method also works.

Code

See regex in use here

```<code>([^,\v]+|(?<=,))(?=,|$)
</code>```

Explanation

([^,\v]+|(?<=,)) Capture either of the following into capture group 1

[^,\v]+ Match one or more of any character not present in the set ,\v. This matches the comma , literally, or vertical whitespace characters \v (such as newline characters)

(?<=,) Match the position where the previous token (using positive lookbehind) is a comma ,

(?=,|$) Positive lookahead to ensure what follows is either a comma , literally or the end of the string $

Body:
Trying to parse comma separated line with regex, but getting inconsistent results:

Regex: ([^,]*),?

The actual value is in match group 1 (excludes the comma).

Expected results:

a,,b  -> 3 matches
a,,b, -> 4 matches
a,,,b -> 4 matches

The number of matches is the number of commas + 1.

The problem is the regex matches at the end even if there is no comma, so getting:

a,,b  -> 4 matches
a,,b, -> 4 matches

Both return 4 matches, even though the lines have a different number of values.

Is it possible to fix the regex so the number of matches is the number of values (commas + 1) without correcting the results in code?

Body:
Brief

It seems your regex is not matching any characters in some locations and working as a sort of assertion (asserting that no character is matched in your group and not followed by a comma ,, which is perfectly valid according to your regex).

This answer is a fix that allows you to match 1 or more of any non-comma , character, or an assertion for a zero-width match all-the-while asserting the position as being preceded by a comma ,.

The best way to go about this would be to split the string on , using a string function, but this method also works.

Code

See regex in use here

([^,\v]+|(?<=,))(?=,|$)

Explanation

([^,\v]+|(?<=,)) Capture either of the following into capture group 1

[^,\v]+ Match one or more of any character not present in the set ,\v. This matches the comma , literally, or vertical whitespace characters \v (such as newline characters)

(?<=,) Match the position where the previous token (using positive lookbehind) is a comma ,

(?=,|$) Positive lookahead to ensure what follows is either a comma , literally or the end of the string $


问:
How to access SAP using Excel VBA?
I am trying to log on to SAP. The Excel VBA code gives me a popup window confirming my information however when I submit the form it does not take me to a new SAP window.

Additionally is there a way to automate all the popup boxes asking for confirmation on my information? I want this code eventually to run at certain times of the day, and I might not be available to input any data.

```<code>Sub login1()
Dim sap As Object
Dim conn As Object

Set sap = CreateObject("SAP.Functions")
Set conn = sap.Connection
conn.System = "System Test Environment"
conn.client = "100"
conn.user = "user"
conn.Password = "password"
conn.Language = "EN"

If conn.logon(0, False) <> True Then
    MsgBox "Logon to the SAP system is not possible", vbOKOnly, "Comment"
Else

End If
End Sub
</code>```

答:
Since you want to "open a new SAP Window" you have to make a different approach!

At First try to open the new instance of SAP from the DOS Commandline with "sapshcut":

```<code>C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system="System Test Environment" -client="100" -user="user" -password="password" -language="EN"
</code>```

If your SystemName has no Spaces (and I belive so!) then you can write it also like:

```<code>C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system=SystemTestEnvironment -client=100 -user=user -password=password -language=EN
</code>```

When this call works with your credentials, then you can transfer it to Excel like this:

```<code>Sub login1()

  Call Shell("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system=SystemTestEnvironment -client=100 -user=user -password=password -language=EN",vbNormalFocus)

End Sub
</code>```

You could also add a transaction by adding "-command=your_tcode" to the String.

If your have spaces in the parameters and you could only start it with -system="System Test Environment" from the Commanline, you will have to escape this in Excel with -system="""System Test Environment""" (!)

Title: How to access SAP using Excel VBA?

Body:
I am trying to log on to SAP. The Excel VBA code gives me a popup window confirming my information however when I submit the form it does not take me to a new SAP window.

Additionally is there a way to automate all the popup boxes asking for confirmation on my information? I want this code eventually to run at certain times of the day, and I might not be available to input any data.

Sub login1()
Dim sap As Object
Dim conn As Object

Set sap = CreateObject("SAP.Functions")
Set conn = sap.Connection
conn.System = "System Test Environment"
conn.client = "100"
conn.user = "user"
conn.Password = "password"
conn.Language = "EN"

If conn.logon(0, False) <> True Then
    MsgBox "Logon to the SAP system is not possible", vbOKOnly, "Comment"
Else

End If
End Sub

Body:
Since you want to "open a new SAP Window" you have to make a different approach!

At First try to open the new instance of SAP from the DOS Commandline with "sapshcut":

C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system="System Test Environment" -client="100" -user="user" -password="password" -language="EN"

If your SystemName has no Spaces (and I belive so!) then you can write it also like:

C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system=SystemTestEnvironment -client=100 -user=user -password=password -language=EN

When this call works with your credentials, then you can transfer it to Excel like this:

Sub login1()

  Call Shell("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapshcut.exe -system=SystemTestEnvironment -client=100 -user=user -password=password -language=EN",vbNormalFocus)

End Sub

You could also add a transaction by adding "-command=your_tcode" to the String.

If your have spaces in the parameters and you could only start it with -system="System Test Environment" from the Commanline, you will have to escape this in Excel with -system="""System Test Environment""" (!)


问:
Python tkinter find which button is clicked
I am trying to implement a game called "Five In a Row".
And I create a 15×15 list to put the buttons. (I used range(16) because I also want a row and a column to display the row number and column number)

I hope my implementation will be like when a button is clicked, it becomes a label.
But I don't know which button the user clicks.

How am I able to implement that? Thanks!

```<code>from tkinter import *
root=Tk()
root.wm_title("Five In a Row")
buttonlst=[ list(range(16)) for i in range(16)]

chess=Label(root,width=2,height=2,text='0')

def p(button):
    gi=button.grid_info()
    x=gi['row']
    y=gi['column']
    button.grid_forget()
    chess.grid(row=x,column=y)
    buttonlst[x][y]=chess

for i in range(16):
    for j in range(16):
        if i==0:
            obj=Label(root,width=2,text=hex(j)[-1].upper())
        elif j==0:
            obj=Label(root,width=2,text=hex(i)[-1].upper())
        else:
            obj=Button(root,relief=FLAT,width=2,command=p(obj))
        obj.grid(row=i,column=j)
        buttonlst[i][j]=obj

root.mainloop()
</code>```

There is a similar question How to determine which button is pressed out of Button grid in Python TKinter?. But I don't quite get that.

答:
To pass the button instance to the command, you must do it in two steps. First, create the button, and then in a second step you configure the command. Also, you must use a lambda to create what's called a closure.

For example:

```<code>obj=Button(root,relief=FLAT,width=2)
obj.configure(command=lambda button=obj: p(button))
</code>```

Body:
I am trying to implement a game called "Five In a Row".
And I create a 15×15 list to put the buttons. (I used range(16) because I also want a row and a column to display the row number and column number)

I hope my implementation will be like when a button is clicked, it becomes a label.
But I don't know which button the user clicks.

How am I able to implement that? Thanks!

from tkinter import *
root=Tk()
root.wm_title("Five In a Row")
buttonlst=[ list(range(16)) for i in range(16)]

chess=Label(root,width=2,height=2,text='0')

def p(button):
    gi=button.grid_info()
    x=gi['row']
    y=gi['column']
    button.grid_forget()
    chess.grid(row=x,column=y)
    buttonlst[x][y]=chess

for i in range(16):
    for j in range(16):
        if i==0:
            obj=Label(root,width=2,text=hex(j)[-1].upper())
        elif j==0:
            obj=Label(root,width=2,text=hex(i)[-1].upper())
        else:
            obj=Button(root,relief=FLAT,width=2,command=p(obj))
        obj.grid(row=i,column=j)
        buttonlst[i][j]=obj

root.mainloop()

There is a similar question How to determine which button is pressed out of Button grid in Python TKinter?. But I don't quite get that.

Body:
To pass the button instance to the command, you must do it in two steps. First, create the button, and then in a second step you configure the command. Also, you must use a lambda to create what's called a closure.

For example:

obj=Button(root,relief=FLAT,width=2)
obj.configure(command=lambda button=obj: p(button))


问:
Is using C# for an embedded device that requires precisely timed TCP messages practical?
Lets say I have a device running Windows CE and there are 2 options: using native c++ and using the .NET Compact Framework using C# to build the application.

I have to establish a connection with an external computer and send out status messages exactly every 0.5 seconds, with only a +/- 10 millisecond error tolerance.

I know you might say that in practice there are too many factors to know the answer, but lets assume that this has been tested with a c++ program, and works, and I wanted to make an equivalent program using C#. The only factor being changed would be the language/framework. Would this be possible, or would the 10 ms +/- error tolerance be too strict to achieve due to C# being a slower garbage collecting language?

答:
If your program does not need much memory and you can avoid long GC pauses then go with C#. It is infinitely easier to work with C# than C++. Raw C# speed is also pretty good. In some cases C# is even faster than C++.

The only thing that you get from C++ is predictability. There is no garbage collection that can surprise you. That is if you manage to avoid memory corruption, duplicate deallocation, pointer screwups, unallocated memory references, etc. etc.


问:
Multipel condition at SQL Case
I have 3 tables to join with:

```<code>ALERT_CASE_HEADER
 - alert_key
ALERT_ITEM
- entity_key
-status_id
-entity_name='Active Alert'
STATUSES
-name
-id
</code>```

Both alert tables use alert_key and entity_key to link. The summation of case only take place if both keys are same value and entity_name='Active Alert' for each of the available status name. And the id column in table STATUSES is linked to ALERT_ITEM.status_id

Can I do something like this? I tried to run the script but it seem very slow.

```<code>SELECT
  SUM(
    CASE
      WHEN s.name = 'Pending'
      AND ach.alert_key = ai.entity_key
      AND ai.entity_name = 'Active Alert'
      THEN 1
      ELSE 0
    END
  ) AS PENDING, SUM(
    CASE
      WHEN s.name = 'new'
      AND ach.alert_key = ai.entity_key
      AND ai.entity_name = 'Active Alert'
      THEN 1
      ELSE 0
    END
  ) AS NEW, SUM(
    CASE
      WHEN s.name = 'cancel'
      AND ach.alert_key = ai.entity_key
      AND ai.entity_name = 'Active Alert'
      THEN 1
      ELSE 0
    END
  ) AS CANCEL
FROM
  STATUSES s, ALERT_CASE_HEADER ach, ALERT_ITEM ai;
</code>```

(From an answer by the asker Nov 14 '17 at 9:53 that should have been an edit:)

The script i am using as per below, just focus on the 2 join statements.The second join is working but not the first one.

```<code> SELECT CUS.ORGUNIT_CODE AS ORGANIZATION_UNITS,
  SUM(
    CASE
      WHEN S.name = 'Pending' THEN 1 ELSE 0
    END
    ) AS PENDING_AUTOCLOSURE,
  SUM(
    CASE
      WHEN S.name = 'New' THEN 1 ELSE 0
    END
    ) AS NEW,
  SUM(
    CASE
      WHEN S.name = 'Under Investigation' THEN 1 ELSE 0
    END
  ) AS UNDER_INVESTIGATION,
  SUM(
    CASE
       WHEN S.Name = 'Escalated' THEN 1 ELSE 0
    END
  ) AS ESCALATED,
   SUM(
    CASE
       WHEN S.Name = 'Recommend True Positive' THEN 1 ELSE 0
    END
  ) AS RECOMMEND_TRUE_POSITIVE,
   SUM(
    CASE
       WHEN S.Name = 'Reopen Under Investigation' THEN 1 ELSE 0
    END
  ) AS REOPEN_UNDER_INVESTIGATION
FROM
  STATUSES S,CUSTOMERS CUS,ALERT_ITEM AI
  JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
  JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
WHERE AI.ENTITY_NAME = 'Active Alert'
AND   AI.ORGUNIT_ID = CUS.ORGUNIT_ID
GROUP BY CUS.ORGUNIT_CODE;
</code>```

答:
S.ID 00904 Invalid Identifier

ORA-00904:    string: invalid identifier

Cause:    The column name entered
  is either missing or invalid.

Action:    Enter a valid column name. A
  valid column name must begin with a letter, be less than or equal to
  30 characters, and consist of only alphanumeric characters and the
  special characters $, _, and #. If it contains other characters, then
  it must be enclosed in double quotation marks. It may not be a
  reserved word.

The problem exists in these lines.

```<code>FROM
  STATUSES S,CUSTOMERS CUS,ALERT_ITEM AI
  JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
  JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
WHERE AI.ENTITY_NAME = 'Active Alert'
</code>```

second line: the alias S is defined for table STATUSES

third line: the alias S is used again for column S.ID that column is invalid It means the table STAUTUSES does not have a column called ID.

second line: you have added 2 more tables, and again you are using commas for that. This is bad, very, very, very, bad. Never mix ANSI style joins with "comma syntax", mixing those styles is a recipe for nightmares.

second & third lines: you have repeated ALERT_ITEM AI

.

```<code>FROM
  STATUSES S

  ,CUSTOMERS CUS  /* change this to explicit join */

  JOIN ALERT_ITEM AI ON S.ID /* <<< wrong column name */   = AI.STATUS_ID
</code>```

STOP using commas between tables. If you remember this you will have a much easier SQL life.

Title: Multipel condition at SQL Case

Body:
I have 3 tables to join with:

ALERT_CASE_HEADER
 - alert_key
ALERT_ITEM
- entity_key
-status_id
-entity_name='Active Alert'
STATUSES
-name
-id

Both alert tables use alert_key and entity_key to link. The summation of case only take place if both keys are same value and entity_name='Active Alert' for each of the available status name. And the id column in table STATUSES is linked to ALERT_ITEM.status_id

Can I do something like this? I tried to run the script but it seem very slow.

SELECT
  SUM(
    CASE
      WHEN s.name = 'Pending'
      AND ach.alert_key = ai.entity_key
      AND ai.entity_name = 'Active Alert'
      THEN 1
      ELSE 0
    END
  ) AS PENDING, SUM(
    CASE
      WHEN s.name = 'new'
      AND ach.alert_key = ai.entity_key
      AND ai.entity_name = 'Active Alert'
      THEN 1
      ELSE 0
    END
  ) AS NEW, SUM(
    CASE
      WHEN s.name = 'cancel'
      AND ach.alert_key = ai.entity_key
      AND ai.entity_name = 'Active Alert'
      THEN 1
      ELSE 0
    END
  ) AS CANCEL
FROM
  STATUSES s, ALERT_CASE_HEADER ach, ALERT_ITEM ai;

(From an answer by the asker Nov 14 '17 at 9:53 that should have been an edit:)

The script i am using as per below, just focus on the 2 join statements.The second join is working but not the first one.

 SELECT CUS.ORGUNIT_CODE AS ORGANIZATION_UNITS,
  SUM(
    CASE
      WHEN S.name = 'Pending' THEN 1 ELSE 0
    END
    ) AS PENDING_AUTOCLOSURE,
  SUM(
    CASE
      WHEN S.name = 'New' THEN 1 ELSE 0
    END
    ) AS NEW,
  SUM(
    CASE
      WHEN S.name = 'Under Investigation' THEN 1 ELSE 0
    END
  ) AS UNDER_INVESTIGATION,
  SUM(
    CASE
       WHEN S.Name = 'Escalated' THEN 1 ELSE 0
    END
  ) AS ESCALATED,
   SUM(
    CASE
       WHEN S.Name = 'Recommend True Positive' THEN 1 ELSE 0
    END
  ) AS RECOMMEND_TRUE_POSITIVE,
   SUM(
    CASE
       WHEN S.Name = 'Reopen Under Investigation' THEN 1 ELSE 0
    END
  ) AS REOPEN_UNDER_INVESTIGATION
FROM
  STATUSES S,CUSTOMERS CUS,ALERT_ITEM AI
  JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
  JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
WHERE AI.ENTITY_NAME = 'Active Alert'
AND   AI.ORGUNIT_ID = CUS.ORGUNIT_ID
GROUP BY CUS.ORGUNIT_CODE;

Body:
S.ID 00904 Invalid Identifier

ORA-00904:    string: invalid identifier

Cause:    The column name entered
  is either missing or invalid.

Action:    Enter a valid column name. A
  valid column name must begin with a letter, be less than or equal to
  30 characters, and consist of only alphanumeric characters and the
  special characters $, _, and #. If it contains other characters, then
  it must be enclosed in double quotation marks. It may not be a
  reserved word.

The problem exists in these lines.

FROM
  STATUSES S,CUSTOMERS CUS,ALERT_ITEM AI
  JOIN ALERT_ITEM AI ON S.ID = AI.STATUS_ID
  JOIN ALERT_CASE_HEADER ACH ON AI.ENTITY_KEY = ACH.ALERT_KEY
WHERE AI.ENTITY_NAME = 'Active Alert'

second line: the alias S is defined for table STATUSES

third line: the alias S is used again for column S.ID that column is invalid It means the table STAUTUSES does not have a column called ID.

second line: you have added 2 more tables, and again you are using commas for that. This is bad, very, very, very, bad. Never mix ANSI style joins with "comma syntax", mixing those styles is a recipe for nightmares.

second & third lines: you have repeated ALERT_ITEM AI

.

FROM
  STATUSES S

  ,CUSTOMERS CUS  /* change this to explicit join */

  JOIN ALERT_ITEM AI ON S.ID /* <<< wrong column name */   = AI.STATUS_ID

STOP using commas between tables. If you remember this you will have a much easier SQL life.