问:
Missing intercepts of OLS Regression models in Python statsmodels
I am running a rolling for example of 100 window OLS regression estimation of the dataset found in this link (https://drive.google.com/drive/folders/0B2Iv8dfU4fTUMVFyYTEtWXlzYkk) as in the following format.

```<code> time     X   Y
0.000543  0  10
0.000575  0  10
0.041324  1  10
0.041331  2  10
0.041336  3  10
0.04134   4  10
  ...
9.987735  55 239
9.987739  56 239
9.987744  57 239
9.987749  58 239
9.987938  59 239
</code>```

The third column (Y) in my dataset is my true value - that's what I wanted to predict (estimate). I want to do a prediction of Y (i.e. predict the current value of Y according to the previous 3 rolling values of X. For this, I have the following python script work using statsmodels.

```<code># /usr/bin/python -tt
import pandas as pd
import numpy as np
import statsmodels.api as sm

df=pd.read_csv('estimated_pred.csv')
df=df.dropna() # to drop nans in case there are any
window = 100
#print(df.index) # to print index
df['a']=None #constant
df['b1']=None #beta1
df['b2']=None #beta2
for i in range(window,len(df)):
    temp=df.iloc[i-window:i,:]
    RollOLS=sm.OLS(temp.loc[:,'Y'],sm.add_constant(temp.loc[:,['time','X']], has_constant = 'add')).fit()
    df.iloc[i,df.columns.get_loc('a')]=RollOLS.params[0]
    df.iloc[i,df.columns.get_loc('b1')]=RollOLS.params[1]
    df.iloc[i,df.columns.get_loc('b2')]=RollOLS.params[2]

# Predicted values in a row
 df['predicted']=df['a'].shift(1)+df['b1'].shift(1)*df['time']+df['b2'].shift(1)*df['X']

#print(df['predicted'])

print(temp)
</code>```

Which gives me a sample output of the following format.

```<code>         time   X   Y        a           b1           b2  predicted
0    0.000543   0  10     None         None         None       NaN
1    0.000575   0  10     None         None         None       NaN
2    0.041324   1  10     None         None         None       NaN
3    0.041331   2  10     None         None         None       NaN
4    0.041336   3  10     None         None         None       NaN
..        ...  ..  ..      ...          ...          ...       ...
50    0.041340   4  10       10            0  1.55431e-15       NaN
51    0.041345   5  10       10   1.7053e-13  7.77156e-16        10
52    0.041350   6  10       10  1.74623e-09 -7.99361e-15        10
53    0.041354   7  10       10  6.98492e-10 -6.21725e-15        10
..        ...  ..  ..      ...          ...          ...       ...
509  0.160835  38  20       20  4.88944e-09 -1.15463e-14        20
510  0.160839  39  20       20  1.86265e-09  5.32907e-15        20
..        ...  ..  ..      ...          ...          ...       ...
</code>```

Finally, I want to include the mean squared error (MSE) for all the prediction (a summary of the OLS regression analysis) values. For example, if we look at row 5, the value of X is 2 and the value of Y is 10. Let's say the prediction value of y at the current row is 6 and therefore the mse will be (10-6)^2. The sm.OLS returns an instance of this class <class 'statsmodels.regression.linear_model.OLS'> when we do print (RollOLS.summary()).

```<code>OLS Regression Results
==============================================================================
Dep. Variable:                      Y   R-squared:                        -inf
Model:                            OLS   Adj. R-squared:                   -inf
Method:                 Least Squares   F-statistic:                    -48.50
Date:                Tue, 04 Jul 2017   Prob (F-statistic):               1.00
Time:                        22:19:18   Log-Likelihood:                 2359.7
No. Observations:                 100   AIC:                            -4713.
Df Residuals:                      97   BIC:                            -4706.
Df Model:                           2
Covariance Type:            nonrobust
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
const        239.0000   2.58e-09   9.26e+10      0.000       239.000   239.000
time        4.547e-13   2.58e-10      0.002      0.999     -5.12e-10  5.13e-10
X          -3.886e-16    1.1e-13     -0.004      0.997     -2.19e-13  2.19e-13
==============================================================================
Omnibus:                       44.322   Durbin-Watson:                   0.000
Prob(Omnibus):                  0.000   Jarque-Bera (JB):               86.471
Skew:                          -1.886   Prob(JB):                     1.67e-19
Kurtosis:                       5.556   Cond. No.                     9.72e+04
==============================================================================
</code>```

But the value of rsquared(print (RollOLS.rsquared)), for example, should have been between 0 and 1 instead of -inf and this seems to be the issue with missing intercepts. If we want to print the mse, we do print (RollOLS.mse_model)... etc as per the documentation. How can we add the intercepts and print the regression statistics with the correct values as we do for the predicted values? What am I doing wrong in here? Or is there another way of doing this using scikit-learnlibraries?

答:
Ok so I prepared this small example so you can visualize what a Poisson regression could do.

```<code>import statsmodels as sm
import matplotlib.pyplot as plt
poi_model = sm.discrete.discrete_model.Poisson

x = np.random.uniform(0, 20,1000)
s = np.random.poisson( x*(0.5) , 1000)
plt.bar(x,s)
plt.show()
</code>```

This generates random poisson counts.

Now the way to fit a poisson regression to the data is the following:

```<code>my_model = poi_model(endog=s, exog=x)
my_model = my_model.fit()
my_model.summary()
</code>```

The summary displays a number of statistics but if you want to compute the mean square error you could do that like so:

```<code>preds = my_model.predict()
mse = np.mean(np.square(preds - s))
</code>```

If you want to predict new values do the following:

```<code>my_model.predict(exog=new_value)
</code>```

Body:
I am running a rolling for example of 100 window OLS regression estimation of the dataset found in this link (https://drive.google.com/drive/folders/0B2Iv8dfU4fTUMVFyYTEtWXlzYkk) as in the following format.

 time     X   Y
0.000543  0  10
0.000575  0  10
0.041324  1  10
0.041331  2  10
0.041336  3  10
0.04134   4  10
  ...
9.987735  55 239
9.987739  56 239
9.987744  57 239
9.987749  58 239
9.987938  59 239

The third column (Y) in my dataset is my true value - that's what I wanted to predict (estimate). I want to do a prediction of Y (i.e. predict the current value of Y according to the previous 3 rolling values of X. For this, I have the following python script work using statsmodels.

# /usr/bin/python -tt
import pandas as pd
import numpy as np
import statsmodels.api as sm

df=pd.read_csv('estimated_pred.csv')
df=df.dropna() # to drop nans in case there are any
window = 100
#print(df.index) # to print index
df['a']=None #constant
df['b1']=None #beta1
df['b2']=None #beta2
for i in range(window,len(df)):
    temp=df.iloc[i-window:i,:]
    RollOLS=sm.OLS(temp.loc[:,'Y'],sm.add_constant(temp.loc[:,['time','X']], has_constant = 'add')).fit()
    df.iloc[i,df.columns.get_loc('a')]=RollOLS.params[0]
    df.iloc[i,df.columns.get_loc('b1')]=RollOLS.params[1]
    df.iloc[i,df.columns.get_loc('b2')]=RollOLS.params[2]

# Predicted values in a row
 df['predicted']=df['a'].shift(1)+df['b1'].shift(1)*df['time']+df['b2'].shift(1)*df['X']

#print(df['predicted'])

print(temp)

Which gives me a sample output of the following format.

         time   X   Y        a           b1           b2  predicted
0    0.000543   0  10     None         None         None       NaN
1    0.000575   0  10     None         None         None       NaN
2    0.041324   1  10     None         None         None       NaN
3    0.041331   2  10     None         None         None       NaN
4    0.041336   3  10     None         None         None       NaN
..        ...  ..  ..      ...          ...          ...       ...
50    0.041340   4  10       10            0  1.55431e-15       NaN
51    0.041345   5  10       10   1.7053e-13  7.77156e-16        10
52    0.041350   6  10       10  1.74623e-09 -7.99361e-15        10
53    0.041354   7  10       10  6.98492e-10 -6.21725e-15        10
..        ...  ..  ..      ...          ...          ...       ...
509  0.160835  38  20       20  4.88944e-09 -1.15463e-14        20
510  0.160839  39  20       20  1.86265e-09  5.32907e-15        20
..        ...  ..  ..      ...          ...          ...       ...

Finally, I want to include the mean squared error (MSE) for all the prediction (a summary of the OLS regression analysis) values. For example, if we look at row 5, the value of X is 2 and the value of Y is 10. Let's say the prediction value of y at the current row is 6 and therefore the mse will be (10-6)^2. The sm.OLS returns an instance of this class <class 'statsmodels.regression.linear_model.OLS'> when we do print (RollOLS.summary()).

OLS Regression Results
==============================================================================
Dep. Variable:                      Y   R-squared:                        -inf
Model:                            OLS   Adj. R-squared:                   -inf
Method:                 Least Squares   F-statistic:                    -48.50
Date:                Tue, 04 Jul 2017   Prob (F-statistic):               1.00
Time:                        22:19:18   Log-Likelihood:                 2359.7
No. Observations:                 100   AIC:                            -4713.
Df Residuals:                      97   BIC:                            -4706.
Df Model:                           2
Covariance Type:            nonrobust
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
const        239.0000   2.58e-09   9.26e+10      0.000       239.000   239.000
time        4.547e-13   2.58e-10      0.002      0.999     -5.12e-10  5.13e-10
X          -3.886e-16    1.1e-13     -0.004      0.997     -2.19e-13  2.19e-13
==============================================================================
Omnibus:                       44.322   Durbin-Watson:                   0.000
Prob(Omnibus):                  0.000   Jarque-Bera (JB):               86.471
Skew:                          -1.886   Prob(JB):                     1.67e-19
Kurtosis:                       5.556   Cond. No.                     9.72e+04
==============================================================================

But the value of rsquared(print (RollOLS.rsquared)), for example, should have been between 0 and 1 instead of -inf and this seems to be the issue with missing intercepts. If we want to print the mse, we do print (RollOLS.mse_model)... etc as per the documentation. How can we add the intercepts and print the regression statistics with the correct values as we do for the predicted values? What am I doing wrong in here? Or is there another way of doing this using scikit-learnlibraries?

Body:
Ok so I prepared this small example so you can visualize what a Poisson regression could do.

import statsmodels as sm
import matplotlib.pyplot as plt
poi_model = sm.discrete.discrete_model.Poisson

x = np.random.uniform(0, 20,1000)
s = np.random.poisson( x*(0.5) , 1000)
plt.bar(x,s)
plt.show()

This generates random poisson counts.

Now the way to fit a poisson regression to the data is the following:

my_model = poi_model(endog=s, exog=x)
my_model = my_model.fit()
my_model.summary()

The summary displays a number of statistics but if you want to compute the mean square error you could do that like so:

preds = my_model.predict()
mse = np.mean(np.square(preds - s))

If you want to predict new values do the following:

my_model.predict(exog=new_value)


来源: stackexchange

问:
spread syntax in typescript
I'm trying to extend a class in an Angular project and I want to pass arguments to the parent class using the rest/spread syntax of ES2015 like the answer to this question

```<code>constructor(...args) {
    super(...args);
}
</code>```

but I get an error Supplied parameters do not match any signature of call target and my app won't compile.

I made a contrived example using the typescript playground. Does anyone know how to get this to work without having to explicitly write the arguments of the parent class methods?

UPDATE: As pointed out by Teddy Sterne I actually don't need to use this for the constructor because it has the same arguments. I actually want to use this for a method that returns an observable. I want to catch errors by overriding the method and returning super.parentMethod(...args).catch(/* deal with error */)

答:
If the Child has the exact same parameters to the constructor as the Parent then you do not need to specify the constructor. The dependencies will be injected that are required by the parent and the parent's constructor will be call implicitly.

class ParentClass {
    constructor(dep1: Dep1, dep2: Dep2) { }
}

class ChildClass {

}
```

<p>If the child has additional dependencies then you will have to re-specify them and then pass them to the Parent's constructor inside the Child's constructor.</p>

<pre class="lang-js prettyprint-override"><code>class ParentClass {
    constructor(dep1: Dep1, dep2: Dep2) { }
}

class ChildClass {
    constructor(dep1: Dep1, dep2: Dep2, dep3: Dep3) {
        super(dep1, dep2);
    }
}
</code>```

ContentLicense: CC BY-SA 3.0

Title: spread syntax in typescript

Body:
I'm trying to extend a class in an Angular project and I want to pass arguments to the parent class using the rest/spread syntax of ES2015 like the answer to this question

constructor(...args) {
    super(...args);
}

but I get an error Supplied parameters do not match any signature of call target and my app won't compile.

I made <a href="https://www.typescriptlang.org/play/#src=class%20Greeter%20%7B%0D%0A%20%20%20%20greeting%3A%20string%3B%0D%0A%20%20%20%20constructor(message%3A%20string)%20%7B%0D%0A%20%20%20%20%20%20%20%20this.greeting%20%3D%20message%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20greet()%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20%22Hello%2C%20%22%20%2B%20this.greeting%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Aclass%20PersonGreeter%20extends%20Greeter%20%7B%0D%0A%20%20%20%20constructor(...args)%20%7B%0D%0A%20%20%20%20%20%20%20%20super(...args)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Alet%20greeter%20%3D%20new%20Greeter(%22world%22)%3B%0D%0A%0D%0Alet%20button%20%3D%20document.createElement('button')%3B%0D%0Abutton.textContent%20%3D%20%22Say%20Hello%22%3B%0D%0Abutton.onclick%20%3D%20function()%20%7B%0D%0A%20%20%20%20alert(greeter.greet())%3B%0D%0A%7D%0D%0A%0D%0Adocument.body.appendChild(button)%3B#src=class%20Greeter%20%7B%0D%0A%20%20%20%20greeting%3A%20string%3B%0D%0A%20%20%20%20constructor(message%3A%20string)%20%7B%0D%0A%20%20%20%20%20%20%20%20this.greeting%20%3D%20message%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20greet()%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20%22Hello%2C%20%22%20%2B%20this.greeting%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%2F*%20This%20doesn't%20work%0D%0Aclass%20PersonGreeter%20extends%20Greeter%20%7B%0D%0A%20%20%20%20constructor(...args)%20%7B%0D%0A%20%20%20%20%20%20%20%20super(...args)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D*%2F%0D%0A%0D%0Aclass%20PersonGreeter%20extends%20Greeter%20%7B%0D%0A%20%20%20%20constructor(name%3A%20string)%20%7B%0D%0A%20%20%20%20%20%20%20%20super(name)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Alet%20greeter%20%3D%20new%20PersonGreeter(%22Mr.%20Smith%22)%3B%0D%0A%0D%0Alet%20button%20%3D%20document.createElement('button')%3B%0D%0Abutton.textContent%20%3D%20%22Say%20Hello%22%3B%0D%0Abutton.onclick%20%3D%20function()%20%7B%0D%0A%20%20%20%20alert(greeter.greet())%3B%0D%0A%7D%0D%0A%0D%0Adocument.body.appendChild(button)%3B#src=class%20Greeter%20%7B%0D%0A%20%20%20%20greeting%3A%20string%3B%0D%0A%20%20%20%20constructor(message%3A%20string)%20%7B%0D%0A%20%20%20%20%20%20%20%20this.greeting%20%3D%20message%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20greet(salutation%3A%20string%20%3D%20'Hello')%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20salutation%20%2B%20%22%2C%20%22%20%2B%20this.greeting%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0A%2F%2F%20This%20doesn't%20work%0D%0Aclass%20PersonGreeter%20extends%20Greeter%20%7B%0D%0A%20%20%20%20constructor(...args)%20%7B%0D%0A%20%20%20%20%20%20%20%20super(...args)%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20greet(...args)%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20super.greet(...args)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Alet%20greeter%20%3D%20new%20PersonGreeter(%22Mr.%20Smith%22)%3B%0D%0A%0D%0Alet%20button%20%3D%20document.createElement('button')%3B%0D%0Abutton.textContent%20%3D%20%22Say%20Hello%22%3B%0D%0Abutton.onclick%20%3D%20function()%20%7B%0D%0A%20%20%20%20alert(greeter.greet())%3B%0D%0A%7D%0D%0A%0D%0Adocument.body.appendChild(button)%3B" rel="nofollow noreferrer">a contrived example using the typescript playground. Does anyone know how to get this to work without having to explicitly write the arguments of the parent class methods?

UPDATE: As pointed out by Teddy Sterne I actually don't need to use this for the constructor because it has the same arguments. I actually want to use this for a method that returns an observable. I want to catch errors by overriding the method and returning super.parentMethod(...args).catch(/* deal with error */)

Body:
If the Child has the exact same parameters to the constructor as the Parent then you do not need to specify the constructor. The dependencies will be injected that are required by the parent and the parent's constructor will be call implicitly.

class ParentClass {
    constructor(dep1: Dep1, dep2: Dep2) { }
}

class ChildClass {

}

If the child has additional dependencies then you will have to re-specify them and then pass them to the Parent's constructor inside the Child's constructor.

class ParentClass {
    constructor(dep1: Dep1, dep2: Dep2) { }
}

class ChildClass {
    constructor(dep1: Dep1, dep2: Dep2, dep3: Dep3) {
        super(dep1, dep2);
    }
}


问:
Understanding Haskell (<-) operator
I was studying the code over at https://rosettacode.org/wiki/Zebra_puzzle#LP-like_version and got somewhat confused.

Here is a minimal example of what is going on in that code.

```<code>import Control.Monad
import Data.List

values :: (Bounded a, Enum a) => [[a]]
values = permutations [minBound..maxBound]

data Nation = English | Swede | Dane
  deriving (Bounded, Eq, Enum, Show)

data Color = Red | Blue | Green
  deriving (Bounded, Eq, Enum, Show)

answers = do

  nation <- values
  begin nation English

  color <- values
  end color Red

  return $ zip nation color

  where
    end xs x = guard $ last xs == x
    begin xs x = guard $ head xs == x

main :: IO ()
main = do
    forM_ answers $ (\answer ->  -- for answer in answers:
      do
        mapM_ print answer
        putStrLn "----" )
    putStrLn "No more solutions!"
</code>```

what is mysterious for me is what is happening in the do block.

I understand from various sources that the a <- b operator does an action b and binds it to a. But what is the action here exactly?

I assumed it was values but if I comment out the begin and end function calls and definitions then haskell does not know what to do with values anymore. I guess this is because the equality test in their definitions is what lets haskell infer the type (am I wrong?).

In that case what exactly is the action here?

Also how does values know which bounded type to apply permutations to? This part seems quite mysterious.

Finally, if I wanted to keep the same
code as above but modify it list out all permutations (not just the
one that satisfy begin and end) how would I do it?

答:
You can translate do notation to list comprehension notation pretty mechanically:

```<code>answers = [ zip nation color
          | nation <- values, head nation == English
          , color <- values, last color == Red
          ]
</code>```

I really don't like this head and last business though.

Title: Understanding Haskell (<-) operator

Body:
I was studying the code over at https://rosettacode.org/wiki/Zebra_puzzle#LP-like_version and got somewhat confused.

Here is a minimal example of what is going on in that code.

import Control.Monad
import Data.List

values :: (Bounded a, Enum a) => [[a]]
values = permutations [minBound..maxBound]

data Nation = English | Swede | Dane
  deriving (Bounded, Eq, Enum, Show)

data Color = Red | Blue | Green
  deriving (Bounded, Eq, Enum, Show)

answers = do

  nation <- values
  begin nation English

  color <- values
  end color Red

  return $ zip nation color

  where
    end xs x = guard $ last xs == x
    begin xs x = guard $ head xs == x

main :: IO ()
main = do
    forM_ answers $ (\answer ->  -- for answer in answers:
      do
        mapM_ print answer
        putStrLn "----" )
    putStrLn "No more solutions!"

what is mysterious for me is what is happening in the do block.

I understand from various sources that the a <- b operator does an action b and binds it to a. But what is the action here exactly?

I assumed it was values but if I comment out the begin and end function calls and definitions then haskell does not know what to do with values anymore. I guess this is because the equality test in their definitions is what lets haskell infer the type (am I wrong?).

In that case what exactly is the action here?

Also how does values know which bounded type to apply permutations to? This part seems quite mysterious.

Finally, if I wanted to keep the same
code as above but modify it list out all permutations (not just the
one that satisfy begin and end) how would I do it?

Body:
You can translate do notation to list comprehension notation pretty mechanically:

answers = [ zip nation color
          | nation <- values, head nation == English
          , color <- values, last color == Red
          ]

I really don't like this head and last business though.


问:
Help me re-understand how to use sine to oscillate a graphic in (Objective) C
I feel silly asking this but I seem to have forgotten how to use sine effectively.

I'm working on an iPad app so I'm in ObjectiveC, and I'm just trying to get a UIView to oscillate slowly. Just using position.y + sin(counter) makes it move so fast it vibrates and I can't seem to define the period to slow it down.

I've found some code samples (mostly for generating sound waves) and they all combine so many things into one line of code I can't easily pull it apart. Can anybody just explain what I should be doing?

答:
Whilst not the answer you're after, you could simply reduce the period you're calling the timer with if it's too fast. (That said, you can also set the duration for the CABasicAnimation - probably a much better approach, as iOS handles the animation for you, can auto-reverse to the initial settings, can be set to loop 'n' times, etc.)

That said, hopefully someone else will provide what you're after.

ContentLicense: CC BY-SA 2.5


问:
How to rename files in subfolder into a specific format
I have files named as RabcdYYMMKKACCOUNT.TXT in the Subfolders of a folder where YYMM is year, month this will change. KK is another identifier, I want all the files to be renamed to MSFKKDNB.ABC, the KK is the identifier in the input file.

Below is the one i tried and the result of it:

```<code>FOR /R %%f IN (*account.txt) DO REN "%%f" *dnb.abc
</code>```

R00531706AUAccount.txt is renamed to R00531706AUAccount.txtdnb.abc

but the output should be MSFAUDNB.abc

答:
This could be done for example with:

```<code>@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R %%I in (???????????account.txt) do (
    set "FileName=%%~nI"
    set "NewFileName=MSF!FileName:~9,2!DNB.abc"
    if not exist "%%~dpI!NewFileName!" (
        ren "%%~fI" "!NewFileName!" 2>nul
        if not exist "%%~dpI!NewFileName!" echo Failed to rename file: "%%~fI"
    ) else (
        echo Cannot rename file: "%%~fI"
    )
)
endlocal
</code>```

The file name of found account text file is assigned to environment variable FileName.

The new name for the file is created by concatenating the fixed parts MSF and DNB.abc with the 2 characters to keep from file name using string substitution and delayed expansion.

Next it is checked if a file with new name does not already exist. Is this the case the file renaming is done otherwise an error message is output.

After renaming the file it is checked if that was successful. A slightly different error is output if renaming failed for example because of a sharing violation.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

echo /?

endlocal /?

for /?

if /?

ren /?

set /?

setlocal /?

Read also the Microsoft article about Using Command Redirection Operators.

Body:
I have files named as RabcdYYMMKKACCOUNT.TXT in the Subfolders of a folder where YYMM is year, month this will change. KK is another identifier, I want all the files to be renamed to MSFKKDNB.ABC, the KK is the identifier in the input file.

Below is the one i tried and the result of it:

FOR /R %%f IN (*account.txt) DO REN "%%f" *dnb.abc

R00531706AUAccount.txt is renamed to R00531706AUAccount.txtdnb.abc

but the output should be MSFAUDNB.abc

Body:
This could be done for example with:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R %%I in (???????????account.txt) do (
    set "FileName=%%~nI"
    set "NewFileName=MSF!FileName:~9,2!DNB.abc"
    if not exist "%%~dpI!NewFileName!" (
        ren "%%~fI" "!NewFileName!" 2>nul
        if not exist "%%~dpI!NewFileName!" echo Failed to rename file: "%%~fI"
    ) else (
        echo Cannot rename file: "%%~fI"
    )
)
endlocal

The file name of found account text file is assigned to environment variable FileName.

The new name for the file is created by concatenating the fixed parts MSF and DNB.abc with the 2 characters to keep from file name using string substitution and delayed expansion.

Next it is checked if a file with new name does not already exist. Is this the case the file renaming is done otherwise an error message is output.

After renaming the file it is checked if that was successful. A slightly different error is output if renaming failed for example because of a sharing violation.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

echo /?

endlocal /?

for /?

if /?

ren /?

set /?

setlocal /?

Read also the Microsoft article about Using Command Redirection Operators.


问:
How to count matching elements in a recursive XQuery function
The following code works, but now I want to specify as a parameter which occurrence of an element specified by the xpath will be affected (replaced, deleted, inserted, etc.)

```<code>  declare function local:replace($doc as node(), $new-content as item()*,
    $target-path as xs:string)  {
    local:transform($doc, $new-content, $target-path, 'replace', "")
  };

  declare function local:transform($node as node(), $new-content as item()*,
        $target-path as xs:string,  $action as xs:string, $path as xs:string)
        as node()+ {
    if ($node instance of element() and concat($path, "/", node-name($node)) = $target-path)
    then
      if ($action = 'insert-before')
      then ($new-content, $node)
      else

      if ($action = 'insert-after')
      then ($node, $new-content)
      else

      if ($action = 'insert-as-child')
      then element {node-name($node)}
        {
        $node/@*
        ,
        $new-content
        ,
          for $child in $node/node()
            return $child
        }
        else

        if ($action = 'replace')
        then $new-content
        else

        if ($action = 'delete')
        then ()
        else ()
    else
        if ($node instance of element())
        then
            element {node-name($node)}

            {
            $node/@*
            ,
            for $child in $node/node()
                return
                  local:transform($child, $new-content, $target-path,  $action, concat($path,  "/", node-name($node)))
            }
         else $node
};

let $doc :=
<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:books>
    <!-- These are my books -->
    <book title='xQuery for Dummys'>
      <author>Jack Wizard</author>
      <details>
        <pages>221</pages>
      </details>
    </book>
    <book title='Mysteries of xQuery'>
      <author>Lost Linda</author>
      <details>
        <replace-this>Goodbye World!</replace-this>
        <pages>40</pages>
      </details>
    </book>
  </fo:books>
</fo:Test>

(: -------- My test -------- :)
let $new-content := <replaced>Hello World!</replaced> return
local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/replace-this')
</code>```

Obviously $global-counter = $global-counter + 1 isn't going to work.  I want to pass in the occurrence I want as another parameter like this:

```<code>    local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/pages', 2)
</code>```

And get this output:

```<code><fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:books>
    <!-- These are my books -->
    <book title='xQuery for Dummys'>
      <author>Jack Wizard</author>
      <details>
        <pages>221</pages>
      </details>
    </book>
    <book title='Mysteries of xQuery'>
      <author>Lost Linda</author>
      <details>
        <replace-this>Goodbye World!</replace-this>
        <replaced>Hello World!</replaced>
      </details>
    </book>
  </fo:books>
</fo:Test>
</code>```

Instead of this unwanted result I'd get with using local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/pages')

```<code><fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:books>
    <!-- These are my books -->
    <book title='xQuery for Dummys'>
      <author>Jack Wizard</author>
      <details>
        <replace-this>Goodbye World!</replace-this>
      </details>
    </book>
    <book title='Mysteries of xQuery'>
      <author>Lost Linda</author>
      <details>
        <replace-this>Goodbye World!</replace-this>
        <replaced>Hello World!</replaced>
      </details>
    </book>
  </fo:books>
</fo:Test>
</code>```

Is there any way to keep count of the number of positive matches I get and add that to the condition?  I'm stumped!

答:
The following provides an example similar to what you are trying to achieve, it does so by using recursion and memorising the path as it goes so that it can compare against your path that you wish to replace.

This uses XQuery 3.1, however it could be rewritten in XQuery 1.0 by encoding/decoding the map structure to/from a sequence or an in-memory XML document.

```<code>xquery version "3.1";

declare namespace fo="http://www.w3.org/1999/XSL/Format";

declare %private function local:push-element($path-stack as map(xs:integer, map(xs:QName, xs:integer)), $element as element(), $depth as xs:integer) as map(xs:integer, map(xs:QName, xs:integer)) {
    let $occurence-map := $path-stack($depth)
    return
      if(not(empty($occurence-map))) then
        let $name-occurs := $occurence-map(node-name($element))
        return
          if($name-occurs) then
            map:put($path-stack, $depth, map:put($occurence-map, node-name($element), $name-occurs + 1))
          else
             map:put($path-stack, $depth, map:put($occurence-map, node-name($element), 1))
      else
        map:put($path-stack, $depth, map { node-name($element) : 1 })

        (: TODO to reduce memory you could remove (pop) any elements from the map which have depth gt $depth :)
};

declare %private function local:children($children as node()*, $replace as xs:string, $replacement as element(), $current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) {
  if($children)then
    let $child := $children[1]
    return
      let $new-path-stack :=
        if($child instance of element())then
          local:push-element($path-stack, $child, count($current-path) + 1)
        else
          $path-stack
      return
      (
        local:replace($child, $replace, $replacement, $current-path, $new-path-stack),
        local:children(subsequence($children, 2), $replace, $replacement, $current-path, $new-path-stack)
      )
  else()
};

declare %private function local:get-occurence($name as xs:QName, $depth as xs:integer, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) {
  $path-stack($depth)($name)
};

declare %private function local:eq-path-with-positions($current-path as xs:QName*,  $path-stack as map(xs:integer, map(xs:QName, xs:integer)), $path-with-positions as xs:string) as xs:boolean {
  let $current-path-with-positions :=
    '/' || string-join(
      for $step-qn at $depth in $current-path
      let $occurence :=  local:get-occurence($step-qn, $depth, $path-stack)
      let $occurence-predicate-str := '[' || $occurence || ']'
      return
        $step-qn || $occurence-predicate-str
      , '/'
    )
  return
    $path-with-positions eq $current-path-with-positions
};

declare %private function local:replace($node as node(), $replace as xs:string, $replacement as element(), $current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) as node() {

    typeswitch($node)

        case document-node()
        return
              document {
                  $node/node() ! local:replace(., $replace, $replacement, $current-path, $path-stack)
              }

        case element()
        return
            let $new-path := ($current-path, node-name($node))
            let $new-path-stack :=
              if(map:size($path-stack) eq 0) then
                local:push-element($path-stack, $node, count($new-path))
              else
                $path-stack
            return
                let $matched-for-replace := local:eq-path-with-positions($new-path, $new-path-stack, $replace)
                return
                  if($matched-for-replace)then
                    $replacement
                  else
                    element {name($node)} {
                        $node/@*,
                        local:children($node/node(), $replace, $replacement, $new-path, $new-path-stack)
                    }

        default return $node

};

declare function local:replace($node as node(), $replace as xs:string, $replacement as element()) as node() {
    let $path-stack as map(xs:integer, map(xs:QName, xs:integer)) := map {}
    return
        local:replace($node, $replace, $replacement, (), $path-stack)
};

let $doc :=
    <fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:books>
        <!-- These are my books -->
        <book title='xQuery for Dummys'>
          <author>Jack Wizard</author>
          <details>
            <pages>221</pages>
          </details>
        </book>
        <book title='Mysteries of xQuery'>
          <author>Lost Linda</author>
          <details>
            <replace-this>Goodbye World!</replace-this>
            <pages>40</pages>
          </details>
        </book>
      </fo:books>
    </fo:Test>
return
    local:replace($doc, '/fo:Test[1]/fo:books[1]/book[2]/details[1]/pages[1]', <replaced>Hello World!</replaced>)
</code>```

Body:
The following code works, but now I want to specify as a parameter which occurrence of an element specified by the xpath will be affected (replaced, deleted, inserted, etc.)

  declare function local:replace($doc as node(), $new-content as item()*,
    $target-path as xs:string)  {
    local:transform($doc, $new-content, $target-path, 'replace', "")
  };

  declare function local:transform($node as node(), $new-content as item()*,
        $target-path as xs:string,  $action as xs:string, $path as xs:string)
        as node()+ {
    if ($node instance of element() and concat($path, "/", node-name($node)) = $target-path)
    then
      if ($action = 'insert-before')
      then ($new-content, $node)
      else

      if ($action = 'insert-after')
      then ($node, $new-content)
      else

      if ($action = 'insert-as-child')
      then element {node-name($node)}
        {
        $node/@*
        ,
        $new-content
        ,
          for $child in $node/node()
            return $child
        }
        else

        if ($action = 'replace')
        then $new-content
        else

        if ($action = 'delete')
        then ()
        else ()
    else
        if ($node instance of element())
        then
            element {node-name($node)}

            {
            $node/@*
            ,
            for $child in $node/node()
                return
                  local:transform($child, $new-content, $target-path,  $action, concat($path,  "/", node-name($node)))
            }
         else $node
};

let $doc :=
<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:books>

    <book title='xQuery for Dummys'>
      <author>Jack Wizard</author>

        <pages>221</pages>

    </book>
    <book title='Mysteries of xQuery'>
      <author>Lost Linda</author>

        <replace-this>Goodbye World!</replace-this>
        <pages>40</pages>

    </book>
  </fo:books>
</fo:Test>

(: -------- My test -------- :)
let $new-content := <replaced>Hello World!</replaced> return
local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/replace-this')

Obviously $global-counter = $global-counter + 1 isn't going to work.  I want to pass in the occurrence I want as another parameter like this:

    local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/pages', 2)

And get this output:

<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:books>

    <book title='xQuery for Dummys'>
      <author>Jack Wizard</author>

        <pages>221</pages>

    </book>
    <book title='Mysteries of xQuery'>
      <author>Lost Linda</author>

        <replace-this>Goodbye World!</replace-this>
        <replaced>Hello World!</replaced>

    </book>
  </fo:books>
</fo:Test>

Instead of this unwanted result I'd get with using local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/pages')

<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:books>

    <book title='xQuery for Dummys'>
      <author>Jack Wizard</author>

        <replace-this>Goodbye World!</replace-this>

    </book>
    <book title='Mysteries of xQuery'>
      <author>Lost Linda</author>

        <replace-this>Goodbye World!</replace-this>
        <replaced>Hello World!</replaced>

    </book>
  </fo:books>
</fo:Test>

Is there any way to keep count of the number of positive matches I get and add that to the condition?  I'm stumped!

Body:
The following provides an example similar to what you are trying to achieve, it does so by using recursion and memorising the path as it goes so that it can compare against your path that you wish to replace.

This uses XQuery 3.1, however it could be rewritten in XQuery 1.0 by encoding/decoding the map structure to/from a sequence or an in-memory XML document.

xquery version "3.1";

declare namespace fo="http://www.w3.org/1999/XSL/Format";

declare %private function local:push-element($path-stack as map(xs:integer, map(xs:QName, xs:integer)), $element as element(), $depth as xs:integer) as map(xs:integer, map(xs:QName, xs:integer)) {
    let $occurence-map := $path-stack($depth)
    return
      if(not(empty($occurence-map))) then
        let $name-occurs := $occurence-map(node-name($element))
        return
          if($name-occurs) then
            map:put($path-stack, $depth, map:put($occurence-map, node-name($element), $name-occurs + 1))
          else
             map:put($path-stack, $depth, map:put($occurence-map, node-name($element), 1))
      else
        map:put($path-stack, $depth, map { node-name($element) : 1 })

        (: TODO to reduce memory you could remove (pop) any elements from the map which have depth gt $depth :)
};

declare %private function local:children($children as node()*, $replace as xs:string, $replacement as element(), $current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) {
  if($children)then
    let $child := $children[1]
    return
      let $new-path-stack :=
        if($child instance of element())then
          local:push-element($path-stack, $child, count($current-path) + 1)
        else
          $path-stack
      return
      (
        local:replace($child, $replace, $replacement, $current-path, $new-path-stack),
        local:children(subsequence($children, 2), $replace, $replacement, $current-path, $new-path-stack)
      )
  else()
};

declare %private function local:get-occurence($name as xs:QName, $depth as xs:integer, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) {
  $path-stack($depth)($name)
};

declare %private function local:eq-path-with-positions($current-path as xs:QName*,  $path-stack as map(xs:integer, map(xs:QName, xs:integer)), $path-with-positions as xs:string) as xs:boolean {
  let $current-path-with-positions :=
    '/' || string-join(
      for $step-qn at $depth in $current-path
      let $occurence :=  local:get-occurence($step-qn, $depth, $path-stack)
      let $occurence-predicate-str := '[' || $occurence || ']'
      return
        $step-qn || $occurence-predicate-str
      , '/'
    )
  return
    $path-with-positions eq $current-path-with-positions
};

declare %private function local:replace($node as node(), $replace as xs:string, $replacement as element(), $current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) as node() {

    typeswitch($node)

        case document-node()
        return
              document {
                  $node/node() ! local:replace(., $replace, $replacement, $current-path, $path-stack)
              }

        case element()
        return
            let $new-path := ($current-path, node-name($node))
            let $new-path-stack :=
              if(map:size($path-stack) eq 0) then
                local:push-element($path-stack, $node, count($new-path))
              else
                $path-stack
            return
                let $matched-for-replace := local:eq-path-with-positions($new-path, $new-path-stack, $replace)
                return
                  if($matched-for-replace)then
                    $replacement
                  else
                    element {name($node)} {
                        $node/@*,
                        local:children($node/node(), $replace, $replacement, $new-path, $new-path-stack)
                    }

        default return $node

};

declare function local:replace($node as node(), $replace as xs:string, $replacement as element()) as node() {
    let $path-stack as map(xs:integer, map(xs:QName, xs:integer)) := map {}
    return
        local:replace($node, $replace, $replacement, (), $path-stack)
};

let $doc :=
    <fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:books>
        <!-- These are my books -->
        <book title='xQuery for Dummys'>
          <author>Jack Wizard</author>
          <details>
            <pages>221</pages>
          </details>
        </book>
        <book title='Mysteries of xQuery'>
          <author>Lost Linda</author>
          <details>
            <replace-this>Goodbye World!</replace-this>
            <pages>40</pages>
          </details>
        </book>
      </fo:books>
    </fo:Test>
return
    local:replace($doc, '/fo:Test[1]/fo:books[1]/book[2]/details[1]/pages[1]', <replaced>Hello World!</replaced>)


问:
TFS 2017 Work item Extension not working
New to this TS scripting so a little help is requested,
I'm trying to create an extension that created a url from 4 work item fields.
example contribution:

```<code>{
"manifestVersion": 1,
"id": "tritech-tfsurl-control",
"version": "0.1.18",
"name": "tritech-tfsurl-control",
"scopes": [ "vso.work", "vso.work_write" ],
"description": "4 fields to a url",
"publisher": "TriTech-Software-Systems",
"icons": {
    "default": "img/logo.png"
},
"targets": [
    {
        "id": "Microsoft.VisualStudio.Services"
    }
],
"tags": [
    "Work Item",
    "Work Item control",
    "Url",
    "Url tfs server"
],
"content": {
    "details": {
        "path": "details.md"
    }
},
"links": {
    "home": {
        "uri": "http://www.Tritech.com"
    }
},
"branding": {
    "color": "rgb(220, 235, 252)",
    "theme": "light"
},
"files": [
    {
        "path": "img",
        "addressable": true
    },
    {
        "path": "index.html",
        "addressable": true
    }
],
"categories": [
    "Plan and track"
],
"contributions": [
    {
        "id": "tfsurlcontrol-action",
        "type": "ms.vss-work-web.work-item-form-control",
        "description": "Work Item fields to create url from",
        "targets": [
            "ms.vss-work-web.work-item-form"
        ],
        "properties": {
            "name": "tfsurl-control",
            "uri": "index.html",
            "height": 90,
            "inputs": [
      {
        "id": "PreviousTFSServer",
        "description": "The TFS server url that has the work item.",
        "type": "WorkItemField",
        "properties": {
          "workItemFieldTypes": [ "String" ]
        },
        "validation": {
          "dataType": "String",
          "isRequired": true
        }
      },
      {
        "id": "TFSCollection",
        "description": "The original tfs collection name",
        "type": "WorkItemField",
        "properties": {
          "workItemFieldTypes": [ "String" ]
        },
        "validation": {
          "dataType": "String",
          "isRequired": true
        }
      },
      {
        "id": "TfsTeamProject",
        "description": "Original TFS project name",
        "type": "WorkItemField",
        "properties": {
          "workItemFieldTypes": [ "String" ]
        },
        "validation": {
          "dataType": "String",
          "isRequired": true
        }
      },
      {
        "id": "TfsWorkItemId",
        "description": "Original work item id",
        "type": "WorkItemField" ,
        "properties": {
          "workItemFieldTypes": [ "Integer" ]
        }
      }
    ]
        }
    }
]
</code>```

}

then in my App.ts file is this,

///<reference types="vss-web-extension-sdk" />
import { Controller } from "./control";
import * as ExtensionContracts from "TFS/WorkItemTracking/ExtensionContracts";
import { WorkItemFormService } from "TFS/WorkItemTracking/Services";

var control: Controller;

var provider = () => {
    return {
  onLoaded: (workItemLoadedArgs: ExtensionContracts.IWorkItemLoadedArgs) => {
            control = new Controller();
        }
    }
};

VSS.register(VSS.getContribution().id, provider);```
</div>
</div>
</p>

<p>this is my Control.ts file,</p>

<p>`
    private _initialize(): void {</p>

```    this._inputs = VSS.getConfiguration().witInputs;
    this._ServerFieldName = this._inputs["PreviousTFSServer"];
    this._CollectionFieldName = this._inputs["TFSCollection"];
    this._ProjectFieldName = this._inputs["TFSTeamProject"];
    this._WorkItemIdFieldName =  this._inputs["TfsWorkItemId"];

    WitService.WorkItemFormService.getService().then(
        (service) => {
            Q.spread<any, any>(
                [ service.getFieldValue(this._ServerFieldName),service.getFieldValue(this._CollectionFieldName),
                service.getFieldValue(this._ProjectFieldName),service.getFieldValue(this._WorkItemIdFieldName)],
                (server: string, collection: string, project:string, id: number) => {
                 this._view = new View(server,collection,project,id);
                 }, this._handleError
            ).then(null, this._handleError);
        },
        this._handleError);
}

private _handleError(error: string): void {
    let errorView = new ErrorView(error);
}
```

<p>}
`
Then I added a view.ts</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>export class View {

    constructor(server: string, collection: string, project: string, id: number) {
        // container div
        if(server)
        {
            var Container = $("<div />");
            var workItemUrl = $("<span></span>").text("Original work item");
            var a = $("<a> </a>");
            var url = 'server + "/" + collection + "/" + project + "/_workitemId?=" + String(id)'
            a.attr("href", url );
            a.attr("target", "_blank");
            a.text("here.");
            workItemUrl.append(a);
            //$('body').empty().append(Container);
            $(".events").append(workItemUrl);
        }
    }
}</code>```

```<code>       <Input Id="PreviousTFSServer" Value="TriTech.Source.Server" />
              <Input Id="TFSCollection" Value="TriTech.Source.Collection" />
              <Input Id="TFSTeamProject" Value="TriTech.Source.Project" />
              <Input Id="TfsWorkItemId" Value="TriTech.Source.Id" />
            </Inputs>
          </ControlContribution>
        </Group>`
</code>```

I started with the latest edition of the vsts-extension-ts-seed-simple-master package. Compiles and creates the extension but I'm not seeing any url or link.

What am I missing?
The WIT has been edited to use the extension.

Web debug shows it is being loaded,

```<code>{"id":"TriTech-Software-Systems.tritech-tfsurl-control.tritech-tfsurlcontrol-action","description":"Work Item fields to create url from","type":"ms.vss-work-web.work-item-form-control-group","targets":["ms.vss-work-web.work-item-form"],"properties":{"name":"tritech-tfsurl-control","uri":"index.html","height":90,"inputs":[{"id":"PreviousTFSServer","description":"The TFS server url that has the work item.","type":"WorkItemField","properties":{"workItemFieldTypes":["String"]},"validation":{"dataType":"String","isRequired":true}},{"id":"TFSCollection","description":"The original tfs collection name","type":"WorkItemField","properties":{"workItemFieldTypes":["String"]},"validation":{"dataType":"String","isRequired":true}},{"id":"TfsTeamProject","description":"Original TFS project name","type":"WorkItemField","properties":{"workItemFieldTypes":["String"]},"validation":{"dataType":"String","isRequired":true}},{"id":"TfsWorkItemId","description":"Original work item id","type":"WorkItemField","properties":{"workItemFieldTypes":["Integer"]}}],"::Attributes":16,"::Version":"0.1.20"}}
</code>```

Thanks in advance.

答:
I ended up using static values and got it working.

var Provider = () => {
        this.ServerfieldName = "Source.Server";
        this.CollectionfieldName = "Source.Collection";
        this.ProjectfieldName = "Source.Project";
        this.WorkItemIdfieldName = "Source.Id";
        this._view = View;

        return{
                onLoaded: (WorkItemLoadedArgs: ExtensionContracts.IWorkItemLoadedArgs) => {
            var deferred = Q.defer();

            WorkItemFormService.getService().then(
            (service) => {
                Q.spread<any, any>(
                    [service.getFieldValue(this.ServerfieldName),service.getFieldValue(this.CollectionfieldName),
                    service.getFieldValue(this.ProjectfieldName),service.getFieldValue(this.WorkItemIdfieldName)],
                                        (server: string, collection: string, project: string, workitemId: number) => {

                                        var data =(`${server}/${collection}/${project}/_workitems#_a=edit&id=${workitemId}`);
                                        if(server){
                                            this._view = new View(data);
                                        }
                                        else{
                                            $('body').empty().append("This is the original Work Item");
                                        }

                    })
                    .catch(function (e) {deferred.reject(e)}
                );
                return deferred.promise;  //.then(null);
            }
        )}

    }
};```
</div>
</div>
</p>

<p>and used a view,</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>/// <reference path="../typings/index.d.ts" />
export class View {

    constructor(public value:string) {

            var Container = $("<div role='link'> </div>");
            Container.addClass("Container");
            Container.attr('tabindex', '0');
            var rdiv = $("<div/>").addClass("rightDiv");
            var ldiv = $("<div/>");
            var help = $("<span></span>").text("Original Tfs work item ");

            var a = $("<a> </a>");
            a.attr("href", value);
            a.attr("target", "_blank");
            a.text("here.");
            help.append(a);
            ldiv.append(help);
            Container.append(rdiv);
            Container.append(ldiv);
            $('body').empty().append(Container);

    }

}</code>```

Body:
New to this TS scripting so a little help is requested,
I'm trying to create an extension that created a url from 4 work item fields.
example contribution:

{
"manifestVersion": 1,
"id": "tritech-tfsurl-control",
"version": "0.1.18",
"name": "tritech-tfsurl-control",
"scopes": [ "vso.work", "vso.work_write" ],
"description": "4 fields to a url",
"publisher": "TriTech-Software-Systems",
"icons": {
    "default": "img/logo.png"
},
"targets": [
    {
        "id": "Microsoft.VisualStudio.Services"
    }
],
"tags": [
    "Work Item",
    "Work Item control",
    "Url",
    "Url tfs server"
],
"content": {
    "details": {
        "path": "details.md"
    }
},
"links": {
    "home": {
        "uri": "http://www.Tritech.com"
    }
},
"branding": {
    "color": "rgb(220, 235, 252)",
    "theme": "light"
},
"files": [
    {
        "path": "img",
        "addressable": true
    },
    {
        "path": "index.html",
        "addressable": true
    }
],
"categories": [
    "Plan and track"
],
"contributions": [
    {
        "id": "tfsurlcontrol-action",
        "type": "ms.vss-work-web.work-item-form-control",
        "description": "Work Item fields to create url from",
        "targets": [
            "ms.vss-work-web.work-item-form"
        ],
        "properties": {
            "name": "tfsurl-control",
            "uri": "index.html",
            "height": 90,
            "inputs": [
      {
        "id": "PreviousTFSServer",
        "description": "The TFS server url that has the work item.",
        "type": "WorkItemField",
        "properties": {
          "workItemFieldTypes": [ "String" ]
        },
        "validation": {
          "dataType": "String",
          "isRequired": true
        }
      },
      {
        "id": "TFSCollection",
        "description": "The original tfs collection name",
        "type": "WorkItemField",
        "properties": {
          "workItemFieldTypes": [ "String" ]
        },
        "validation": {
          "dataType": "String",
          "isRequired": true
        }
      },
      {
        "id": "TfsTeamProject",
        "description": "Original TFS project name",
        "type": "WorkItemField",
        "properties": {
          "workItemFieldTypes": [ "String" ]
        },
        "validation": {
          "dataType": "String",
          "isRequired": true
        }
      },
      {
        "id": "TfsWorkItemId",
        "description": "Original work item id",
        "type": "WorkItemField" ,
        "properties": {
          "workItemFieldTypes": [ "Integer" ]
        }
      }
    ]
        }
    }
]

}

then in my App.ts file is this,

///<reference types="vss-web-extension-sdk" />
import { Controller } from "./control";
import * as ExtensionContracts from "TFS/WorkItemTracking/ExtensionContracts";
import { WorkItemFormService } from "TFS/WorkItemTracking/Services";

var control: Controller;

var provider = () => {
    return {
  onLoaded: (workItemLoadedArgs: ExtensionContracts.IWorkItemLoadedArgs) => {
            control = new Controller();
        }
    }
};

VSS.register(VSS.getContribution().id, provider);

this is my Control.ts file,

`
    private _initialize(): void {

    this._inputs = VSS.getConfiguration().witInputs;
    this._ServerFieldName = this._inputs["PreviousTFSServer"];
    this._CollectionFieldName = this._inputs["TFSCollection"];
    this._ProjectFieldName = this._inputs["TFSTeamProject"];
    this._WorkItemIdFieldName =  this._inputs["TfsWorkItemId"];

    WitService.WorkItemFormService.getService().then(
        (service) => {
            Q.spread<any, any>(
                [ service.getFieldValue(this._ServerFieldName),service.getFieldValue(this._CollectionFieldName),
                service.getFieldValue(this._ProjectFieldName),service.getFieldValue(this._WorkItemIdFieldName)],
                (server: string, collection: string, project:string, id: number) => {
                 this._view = new View(server,collection,project,id);
                 }, this._handleError
            ).then(null, this._handleError);
        },
        this._handleError);
}

private _handleError(error: string): void {
    let errorView = new ErrorView(error);
}

}
`
Then I added a view.ts

export class View {

    constructor(server: string, collection: string, project: string, id: number) {
        // container div
        if(server)
        {
            var Container = $("
");
            var workItemUrl = $("").text("Original work item");
            var a = $(" ");
            var url = 'server + "/" + collection + "/" + project + "/_workitemId?=" + String(id)'
            a.attr("href", url );
            a.attr("target", "_blank");
            a.text("here.");
            workItemUrl.append(a);
            //$('body').empty().append(Container);
            $(".events").append(workItemUrl);
        }
    }
}

       <Input Id="PreviousTFSServer" Value="TriTech.Source.Server" />
              <Input Id="TFSCollection" Value="TriTech.Source.Collection" />
              <Input Id="TFSTeamProject" Value="TriTech.Source.Project" />
              <Input Id="TfsWorkItemId" Value="TriTech.Source.Id" />
            </Inputs>
          </ControlContribution>
        </Group>`

I started with the latest edition of the vsts-extension-ts-seed-simple-master package. Compiles and creates the extension but I'm not seeing any url or link.

What am I missing?
The WIT has been edited to use the extension.

Web debug shows it is being loaded,

{"id":"TriTech-Software-Systems.tritech-tfsurl-control.tritech-tfsurlcontrol-action","description":"Work Item fields to create url from","type":"ms.vss-work-web.work-item-form-control-group","targets":["ms.vss-work-web.work-item-form"],"properties":{"name":"tritech-tfsurl-control","uri":"index.html","height":90,"inputs":[{"id":"PreviousTFSServer","description":"The TFS server url that has the work item.","type":"WorkItemField","properties":{"workItemFieldTypes":["String"]},"validation":{"dataType":"String","isRequired":true}},{"id":"TFSCollection","description":"The original tfs collection name","type":"WorkItemField","properties":{"workItemFieldTypes":["String"]},"validation":{"dataType":"String","isRequired":true}},{"id":"TfsTeamProject","description":"Original TFS project name","type":"WorkItemField","properties":{"workItemFieldTypes":["String"]},"validation":{"dataType":"String","isRequired":true}},{"id":"TfsWorkItemId","description":"Original work item id","type":"WorkItemField","properties":{"workItemFieldTypes":["Integer"]}}],"::Attributes":16,"::Version":"0.1.20"}}

Thanks in advance.

Body:
I ended up using static values and got it working.

var Provider = () => {
        this.ServerfieldName = "Source.Server";
        this.CollectionfieldName = "Source.Collection";
        this.ProjectfieldName = "Source.Project";
        this.WorkItemIdfieldName = "Source.Id";
        this._view = View;

        return{
                onLoaded: (WorkItemLoadedArgs: ExtensionContracts.IWorkItemLoadedArgs) => {
            var deferred = Q.defer();

            WorkItemFormService.getService().then(
            (service) => {
                Q.spread<any, any>(
                    [service.getFieldValue(this.ServerfieldName),service.getFieldValue(this.CollectionfieldName),
                    service.getFieldValue(this.ProjectfieldName),service.getFieldValue(this.WorkItemIdfieldName)],
                                        (server: string, collection: string, project: string, workitemId: number) => {

                                        var data =(`${server}/${collection}/${project}/_workitems#_a=edit&id=${workitemId}`);
                                        if(server){
                                            this._view = new View(data);
                                        }
                                        else{
                                            $('body').empty().append("This is the original Work Item");
                                        }

                    })
                    .catch(function (e) {deferred.reject(e)}
                );
                return deferred.promise;  //.then(null);
            }
        )}

    }
};

and used a view,

/// <reference path="../typings/index.d.ts" />
export class View {

    constructor(public value:string) {

            var Container = $("<div role='link'> </div>");
            Container.addClass("Container");
            Container.attr('tabindex', '0');
            var rdiv = $("<div/>").addClass("rightDiv");
            var ldiv = $("<div/>");
            var help = $("<span></span>").text("Original Tfs work item ");

            var a = $("<a> </a>");
            a.attr("href", value);
            a.attr("target", "_blank");
            a.text("here.");
            help.append(a);
            ldiv.append(help);
            Container.append(rdiv);
            Container.append(ldiv);
            $('body').empty().append(Container);

    }

}


问:
Javafx IO Exception about "implements Serializable"
I have some trouble on javafx FILE IO. I have implemented Serializable but there is also some wrong. Thank you for your help.

1.Appdata class

```<code>    package data;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import model.*;

public class AppData implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    public static final ObservableList<Customer> cusInfo = FXCollections.observableArrayList();
    static{
        Customer Raven = new Customer();
        Raven.setName(new SimpleStringProperty("Raven"));
        Raven.setPassword("raven09");
        Customer Messi = new Customer();
        Messi.setName(new SimpleStringProperty("Messi"));
        Messi.setPassword("messi10");
        Customer Ronaldo = new Customer();
        Ronaldo.setName(new SimpleStringProperty("Ronaldo"));
        Ronaldo.setPassword("ronaldo07");
        Customer Neymar = new Customer();
        Neymar.setName(new SimpleStringProperty("Neymar"));
        Neymar.setPassword("neymar11");

        Account RavenFund = new Account();
        RavenFund.setBalance("1000000");
        RavenFund.setName(new SimpleStringProperty("RavenFund"));
        RavenFund.setLimit("200000");
        RavenFund.setType("private");
        Account MeRo = new Account();
        MeRo.setBalance("200000");
        MeRo.setName(new SimpleStringProperty("MeRo"));
        MeRo.setLimit("60000");
        MeRo.setType("private");
        Account Barcelona = new Account();
        Barcelona.setBalance("40000");
        Barcelona.setName(new SimpleStringProperty("Barcelona"));
        Barcelona.setLimit("680000");
        Barcelona.setType("business");
        Account Madrid = new Account();
        Madrid.setBalance("70651");
        Madrid.setName(new SimpleStringProperty("Madrid"));
        Madrid.setLimit("8000");
        Madrid.setType("business");

        Raven.add(RavenFund);
        Raven.add(Barcelona);
        Messi.add(MeRo);
        Messi.add(Barcelona);
        Ronaldo.add(MeRo);
        Ronaldo.add(Madrid);
        Neymar.add(Barcelona);
        cusInfo.add(Raven);
        cusInfo.add(Messi);
        cusInfo.add(Ronaldo);
        cusInfo.add(Neymar);
    }
    public static void writeObject() {
        try {
            FileOutputStream outStream = new FileOutputStream("appdata.txt");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outStream);

            objectOutputStream.writeObject(cusInfo);
            outStream.close();
            System.out.println("successful");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void readObject(){
        FileInputStream freader;
        try {
            freader = new FileInputStream("appdata.txt");
            ObjectInputStream objectInputStream = new ObjectInputStream(freader);
            ObservableList<Customer> cusINFO =FXCollections.observableArrayList();
             cusINFO = (ObservableList<Customer>) objectInputStream.readObject();
             //System.out.println("The name is " + cusINFO.get("name"));

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
</code>```

2.Account class

```<code>    package model;

import java.io.Serializable;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 * @author dell
 *
 */
public class Account implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
        private StringProperty name;
        private StringProperty type;
        private StringProperty limit;
        private StringProperty balance;

        public Account(){
            name = new SimpleStringProperty();
            type = new SimpleStringProperty();
            limit= new SimpleStringProperty();
            balance= new SimpleStringProperty();
        }
        public String getType() {
            return type.get();
        }
        public void setType(String type) {
            this.type.set(type);
        }
        public String getLimit() {
            return limit.get();
        }
        public void setLimit(String limit) {
            this.limit.set(limit);
        }
        public String getBalance() {
            return balance.get();
        }
        public void setBalance(String balance) {
            this.balance.set(balance);
        }
        public StringProperty getName() {
            return name;
        }
        public void setName(StringProperty name) {
            this.name = name;
        }
    }
</code>```

3.Customer class

```<code>    package model;

import java.io.Serializable;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
 * @author Raven Xu
 * @version 1.2
 * @version 1.1
 *
 */
public class Customer implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private StringProperty name;
    private StringProperty password;
    private ObservableList<Account> accounts;

    public Customer() {
        accounts = FXCollections.observableArrayList();
        name = new SimpleStringProperty();
        password = new SimpleStringProperty();
    }

    public StringProperty getName() {
        return name;
    }

    public void setName(StringProperty name) {
        this.name = name;
    }

    public String getPassword() {
        return password.get();
    }

    public void setPassword(String password) {
        this.password.set(password);
    }

    public void add(Account a) {
        accounts.add(a);
    }

    public ObservableList<Account> getAccounts() {
        return accounts;
    }
}
</code>```

4.Main class

```<code>    package view;

import data.AppData;
import javafx.application.Application;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import stage.WelcomeStage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            AppData.writeObject();
            //AppData.readObject();
            primaryStage = WelcomeStage.getStage();
            primaryStage.getIcons().add(new Image("file:resources/images/RBClogo.png"));
            } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</code>```

5.Error Information

```<code>java.io.NotSerializableException: com.sun.javafx.collections.ObservableListWrapper
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at data.AppData.writeObject(AppData.java:74)
    at view.Main.start(Main.java:13)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Unknown Source)
</code>```

My English is very good. I really really thank you if you can help me.

答:
First, you are trying to pass an ObservableList to ObjectOutputStream.writeObject.  As fabian points out, that ObservableList was returned by FXCollections.observableArrayList() and is in no way guaranteed to be serializable.

Even if that ObservableList were serializable, serializing it would automatically serialize its elements—Customer instances—which are themselves going to have serialization problems.  The non-static fields of Customer are SimpleStringProperty instances, which are not serializable, and an ObservableList obtained from another call to FXCollections.observableArrayList(), which we’ve already established is not guaranteed to be serializable.

As the author of a class, if you make the class implement Serializable, you are responsible for making sure its fields can be serialized.  One way, of course, is to make sure each field’s type is a serializable type.  But since you’re using JavaFX properties, that isn’t an option.  This means you have to handle the serialization yourself.  Luckily, the process for doing this is described fairly well in the documentation for the Serializable interface:

Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

private void writeObject(java.io.ObjectOutputStream out)

  throws IOException

  private void readObject(java.io.ObjectInputStream in)

  throws IOException, ClassNotFoundException

…

The writeObject method is responsible for writing the state of the object for its particular class so that the corresponding readObject method can restore it. The default mechanism for saving the Object's fields can be invoked by calling out.defaultWriteObject. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

The readObject method is responsible for reading from the stream and restoring the classes fields. It may call in.defaultReadObject to invoke the default mechanism for restoring the object's non-static and non-transient fields. The defaultReadObject method uses information in the stream to assign the fields of the object saved in the stream with the correspondingly named fields in the current object. This handles the case when the class has evolved to add new fields. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

What this means is that your class needs to add a writeObject method to do its own serialization, writing objects of types that are known to be serializable:

```<code>public class Customer
implements Serializable {
    private static final long serialVersionUID = 1;

    private transient StringProperty name;
    private transient StringProperty password;
    private transient ObservableList<Account> accounts;

    // ...

    /**
     * Performs custom serialization of this instance.
     * Automatically invoked by Java when this instance is serialized.
     *
     * @param out stream to write this object to
     *
     * @throws IOException if any error occurs while writing
     *
     * @serialData String representing {@link #name};
     *             String representing {@link #password};
     *             Account[] array representing {@link #accounts}
     *
     * @see #readObject(ObjectInputStream)
     */
    private void writeObject(ObjectOutputStream out)
    throws IOException {

        out.defaultWriteObject();   // always call this first

        out.writeObject(name.get());
        out.writeObject(password.get());
        out.writeObject(accounts.toArray(new Account[0]));
    }

    /**
     * Performs custom deserialization of transient fields.
     * Automatically invoked by Java during deserialization.
     *
     * @param in stream from which this object is being read
     *
     * @throws IOException if any error occurs while reading
     * @throws ClassNotFoundException if any object is read which belongs to an unknown class
     *
     * @see #writeObject(ObjectOutputStream)
     */
    private void readObject(ObjectInputStream in)
    throws IOException,
           ClassNotFoundException {

        in.defaultReadObject();    // always call this first

        name = new SimpleStringProperty((String) in.readObject());
        password = new SimpleStringProperty((String) in.readObject());
        accounts = FXCollections.observableArrayList((Account[]) in.readObject());
    }
</code>```

Note the use of the transient keyword on the JavaFX properties and ObservableList.  This prevents them from being automatically serialized and deserialized.  The writeObject method does the work instead, passing objects which are known to correctly implement Serializable:  Strings and a Java array.

The @serialData javadoc tag is not required, but it’s a very good idea, as it documents exactly what is getting written in place of each transient field.

Note that deserialization does not invoke any constructors.*  All constructors are bypassed, so the readObject must make sure to initialize non-static, non-transient fields.  If it doesn’t, they will be null (or zero/false in the case of numeric/boolean fields).

In the above code, I have chosen to store the accounts ObservableList in the serialized data stream as an array.  There is a good reason for this:  While I could use an ArrayList or other List implementation known to be serializable, the act of casting the Object returned by ObjectInputStream.readObject would not be safe.  Due to type erasure, casting an object to List<Account> is not safe, since it tells the compiler to blindly assume the List contains Account objects even though there is no guarantee of that at runtime.  On the other hand, array types are fully present (reified) at runtime, so when the code attempts to cast to Account[], it is guaranteed to either succeed (and thus guarantee every element is in fact an Account instance), or throw a ClassCastException.

That takes care of the Customer class.  However, since serializing a Customer instance also involves serializing zero or more Account instances, the Account class must be given the same treatment:

```<code>public class Account
implements Serializable {
    private static final long serialVersionUID = 1;

    private transient StringProperty name;
    private transient StringProperty type;
    private transient StringProperty limit;
    private transient StringProperty balance;

    // ...

    /**
     * [javadoc omitted;  should be similar to javadoc of Customer.writeObject]
     *
     * @serialData String representation of {@link #name};
     *             String representation of {@link #type};
     *             String representation of {@link #limit};
     *             String representation of {@link #balance}
     */
    private void writeObject(ObjectOutputStream out)
    throws IOException {

        out.defaultWriteObject();   // always call this first

        out.writeObject(name.get());
        out.writeObject(type.get());
        out.writeObject(limit.get());
        out.writeObject(balance.get());
    }

    /**
     * [javadoc omitted;  should be similar to javadoc of Customer.readObject]
     */
    private void readObject(ObjectInputStream in)
    throws IOException,
           ClassNotFoundException {

        in.defaultReadObject();    // always call this first

        name = new SimpleStringProperty((String) in.readObject());
        type = new SimpleStringProperty((String) in.readObject());
        limit = new SimpleStringProperty((String) in.readObject());
        balance = new SimpleStringProperty((String) in.readObject());
    }
</code>```

(Are you sure you want to store a balance as a String instead of, say, a BigDecimal?)

I should also point out that the getName and setName methods of both Customer and Account are not JavaFX bean compliant.  If you look at any JavaFX class, such as Stage, you will see that each writable (as opposed to read-only) property has three methods.  Consider, for example, the title property of Stage:

```<code>public StringProperty titleProperty();
public String getTitle();
public void setTitle(String newTitle);
</code>```

As you can see, standard JavaFX convention is to make the StringProperty object itself unchangeable, while making the StringProperty’s contained value modifiable.  The get/set methods use String, but never StringProperty.

* Technically, there are circumstances where deserialization can invoke constructors, but those circumstances do not apply to any class which implements or inherits the Serializable interface.

Body:
I have some trouble on javafx FILE IO. I have implemented Serializable but there is also some wrong. Thank you for your help.

1.Appdata class

    package data;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import model.*;

public class AppData implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    public static final ObservableList<Customer> cusInfo = FXCollections.observableArrayList();
    static{
        Customer Raven = new Customer();
        Raven.setName(new SimpleStringProperty("Raven"));
        Raven.setPassword("raven09");
        Customer Messi = new Customer();
        Messi.setName(new SimpleStringProperty("Messi"));
        Messi.setPassword("messi10");
        Customer Ronaldo = new Customer();
        Ronaldo.setName(new SimpleStringProperty("Ronaldo"));
        Ronaldo.setPassword("ronaldo07");
        Customer Neymar = new Customer();
        Neymar.setName(new SimpleStringProperty("Neymar"));
        Neymar.setPassword("neymar11");

        Account RavenFund = new Account();
        RavenFund.setBalance("1000000");
        RavenFund.setName(new SimpleStringProperty("RavenFund"));
        RavenFund.setLimit("200000");
        RavenFund.setType("private");
        Account MeRo = new Account();
        MeRo.setBalance("200000");
        MeRo.setName(new SimpleStringProperty("MeRo"));
        MeRo.setLimit("60000");
        MeRo.setType("private");
        Account Barcelona = new Account();
        Barcelona.setBalance("40000");
        Barcelona.setName(new SimpleStringProperty("Barcelona"));
        Barcelona.setLimit("680000");
        Barcelona.setType("business");
        Account Madrid = new Account();
        Madrid.setBalance("70651");
        Madrid.setName(new SimpleStringProperty("Madrid"));
        Madrid.setLimit("8000");
        Madrid.setType("business");

        Raven.add(RavenFund);
        Raven.add(Barcelona);
        Messi.add(MeRo);
        Messi.add(Barcelona);
        Ronaldo.add(MeRo);
        Ronaldo.add(Madrid);
        Neymar.add(Barcelona);
        cusInfo.add(Raven);
        cusInfo.add(Messi);
        cusInfo.add(Ronaldo);
        cusInfo.add(Neymar);
    }
    public static void writeObject() {
        try {
            FileOutputStream outStream = new FileOutputStream("appdata.txt");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outStream);

            objectOutputStream.writeObject(cusInfo);
            outStream.close();
            System.out.println("successful");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void readObject(){
        FileInputStream freader;
        try {
            freader = new FileInputStream("appdata.txt");
            ObjectInputStream objectInputStream = new ObjectInputStream(freader);
            ObservableList<Customer> cusINFO =FXCollections.observableArrayList();
             cusINFO = (ObservableList<Customer>) objectInputStream.readObject();
             //System.out.println("The name is " + cusINFO.get("name"));

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

2.Account class

    package model;

import java.io.Serializable;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 * @author dell
 *
 */
public class Account implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
        private StringProperty name;
        private StringProperty type;
        private StringProperty limit;
        private StringProperty balance;

        public Account(){
            name = new SimpleStringProperty();
            type = new SimpleStringProperty();
            limit= new SimpleStringProperty();
            balance= new SimpleStringProperty();
        }
        public String getType() {
            return type.get();
        }
        public void setType(String type) {
            this.type.set(type);
        }
        public String getLimit() {
            return limit.get();
        }
        public void setLimit(String limit) {
            this.limit.set(limit);
        }
        public String getBalance() {
            return balance.get();
        }
        public void setBalance(String balance) {
            this.balance.set(balance);
        }
        public StringProperty getName() {
            return name;
        }
        public void setName(StringProperty name) {
            this.name = name;
        }
    }

3.Customer class

    package model;

import java.io.Serializable;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
 * @author Raven Xu
 * @version 1.2
 * @version 1.1
 *
 */
public class Customer implements Serializable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private StringProperty name;
    private StringProperty password;
    private ObservableList<Account> accounts;

    public Customer() {
        accounts = FXCollections.observableArrayList();
        name = new SimpleStringProperty();
        password = new SimpleStringProperty();
    }

    public StringProperty getName() {
        return name;
    }

    public void setName(StringProperty name) {
        this.name = name;
    }

    public String getPassword() {
        return password.get();
    }

    public void setPassword(String password) {
        this.password.set(password);
    }

    public void add(Account a) {
        accounts.add(a);
    }

    public ObservableList<Account> getAccounts() {
        return accounts;
    }
}

4.Main class

    package view;

import data.AppData;
import javafx.application.Application;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import stage.WelcomeStage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            AppData.writeObject();
            //AppData.readObject();
            primaryStage = WelcomeStage.getStage();
            primaryStage.getIcons().add(new Image("file:resources/images/RBClogo.png"));
            } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

5.Error Information

java.io.NotSerializableException: com.sun.javafx.collections.ObservableListWrapper
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at data.AppData.writeObject(AppData.java:74)
    at view.Main.start(Main.java:13)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Unknown Source)

My English is very good. I really really thank you if you can help me.

Body:
First, you are trying to pass an ObservableList to ObjectOutputStream.writeObject.  As fabian points out, that ObservableList was returned by FXCollections.observableArrayList() and is in no way guaranteed to be serializable.

Even if that ObservableList were serializable, serializing it would automatically serialize its elements—Customer instances—which are themselves going to have serialization problems.  The non-static fields of Customer are SimpleStringProperty instances, which are not serializable, and an ObservableList obtained from another call to FXCollections.observableArrayList(), which we’ve already established is not guaranteed to be serializable.

As the author of a class, if you make the class implement Serializable, you are responsible for making sure its fields can be serialized.  One way, of course, is to make sure each field’s type is a serializable type.  But since you’re using JavaFX properties, that isn’t an option.  This means you have to handle the serialization yourself.  Luckily, the process for doing this is described fairly well in the documentation for the Serializable interface:

Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

private void writeObject(java.io.ObjectOutputStream out)

  throws IOException

  private void readObject(java.io.ObjectInputStream in)

  throws IOException, ClassNotFoundException

…

The writeObject method is responsible for writing the state of the object for its particular class so that the corresponding readObject method can restore it. The default mechanism for saving the Object's fields can be invoked by calling out.defaultWriteObject. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

The readObject method is responsible for reading from the stream and restoring the classes fields. It may call in.defaultReadObject to invoke the default mechanism for restoring the object's non-static and non-transient fields. The defaultReadObject method uses information in the stream to assign the fields of the object saved in the stream with the correspondingly named fields in the current object. This handles the case when the class has evolved to add new fields. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

What this means is that your class needs to add a writeObject method to do its own serialization, writing objects of types that are known to be serializable:

public class Customer
implements Serializable {
    private static final long serialVersionUID = 1;

    private transient StringProperty name;
    private transient StringProperty password;
    private transient ObservableList<Account> accounts;

    // ...

    /**
     * Performs custom serialization of this instance.
     * Automatically invoked by Java when this instance is serialized.
     *
     * @param out stream to write this object to
     *
     * @throws IOException if any error occurs while writing
     *
     * @serialData String representing {@link #name};
     *             String representing {@link #password};
     *             Account[] array representing {@link #accounts}
     *
     * @see #readObject(ObjectInputStream)
     */
    private void writeObject(ObjectOutputStream out)
    throws IOException {

        out.defaultWriteObject();   // always call this first

        out.writeObject(name.get());
        out.writeObject(password.get());
        out.writeObject(accounts.toArray(new Account[0]));
    }

    /**
     * Performs custom deserialization of transient fields.
     * Automatically invoked by Java during deserialization.
     *
     * @param in stream from which this object is being read
     *
     * @throws IOException if any error occurs while reading
     * @throws ClassNotFoundException if any object is read which belongs to an unknown class
     *
     * @see #writeObject(ObjectOutputStream)
     */
    private void readObject(ObjectInputStream in)
    throws IOException,
           ClassNotFoundException {

        in.defaultReadObject();    // always call this first

        name = new SimpleStringProperty((String) in.readObject());
        password = new SimpleStringProperty((String) in.readObject());
        accounts = FXCollections.observableArrayList((Account[]) in.readObject());
    }

Note the use of the transient keyword on the JavaFX properties and ObservableList.  This prevents them from being automatically serialized and deserialized.  The writeObject method does the work instead, passing objects which are known to correctly implement Serializable:  Strings and a Java array.

The @serialData javadoc tag is not required, but it’s a very good idea, as it documents exactly what is getting written in place of each transient field.

Note that deserialization does not invoke any constructors.*  All constructors are bypassed, so the readObject must make sure to initialize non-static, non-transient fields.  If it doesn’t, they will be null (or zero/false in the case of numeric/boolean fields).

In the above code, I have chosen to store the accounts ObservableList in the serialized data stream as an array.  There is a good reason for this:  While I could use an ArrayList or other List implementation known to be serializable, the act of casting the Object returned by ObjectInputStream.readObject would not be safe.  Due to type erasure, casting an object to List<Account> is not safe, since it tells the compiler to blindly assume the List contains Account objects even though there is no guarantee of that at runtime.  On the other hand, array types are fully present (reified) at runtime, so when the code attempts to cast to Account[], it is guaranteed to either succeed (and thus guarantee every element is in fact an Account instance), or throw a ClassCastException.

That takes care of the Customer class.  However, since serializing a Customer instance also involves serializing zero or more Account instances, the Account class must be given the same treatment:

public class Account
implements Serializable {
    private static final long serialVersionUID = 1;

    private transient StringProperty name;
    private transient StringProperty type;
    private transient StringProperty limit;
    private transient StringProperty balance;

    // ...

    /**
     * [javadoc omitted;  should be similar to javadoc of Customer.writeObject]
     *
     * @serialData String representation of {@link #name};
     *             String representation of {@link #type};
     *             String representation of {@link #limit};
     *             String representation of {@link #balance}
     */
    private void writeObject(ObjectOutputStream out)
    throws IOException {

        out.defaultWriteObject();   // always call this first

        out.writeObject(name.get());
        out.writeObject(type.get());
        out.writeObject(limit.get());
        out.writeObject(balance.get());
    }

    /**
     * [javadoc omitted;  should be similar to javadoc of Customer.readObject]
     */
    private void readObject(ObjectInputStream in)
    throws IOException,
           ClassNotFoundException {

        in.defaultReadObject();    // always call this first

        name = new SimpleStringProperty((String) in.readObject());
        type = new SimpleStringProperty((String) in.readObject());
        limit = new SimpleStringProperty((String) in.readObject());
        balance = new SimpleStringProperty((String) in.readObject());
    }

(Are you sure you want to store a balance as a String instead of, say, a BigDecimal?)

I should also point out that the getName and setName methods of both Customer and Account are not JavaFX bean compliant.  If you look at any JavaFX class, such as Stage, you will see that each writable (as opposed to read-only) property has three methods.  Consider, for example, the title property of Stage:

public StringProperty titleProperty();
public String getTitle();
public void setTitle(String newTitle);

As you can see, standard JavaFX convention is to make the StringProperty object itself unchangeable, while making the StringProperty’s contained value modifiable.  The get/set methods use String, but never StringProperty.

* Technically, there are circumstances where deserialization can invoke constructors, but those circumstances do not apply to any class which implements or inherits the Serializable interface.

ContentLicense: CC BY-SA 4.0