问:
UserAuthorities in Basic Auth with Spring Security for REST API
I have been trying to secure my Spring Rest API with Basic Auth using Spring Security. I want it to be configured so that users are stored in a database and that they have access to different endpoints depending on their role.
For simplicity, in the below example all endpoints require "ADMIN" role.
I think I configured everything correctly (based on some online tutorials), however it seems like Security cannot deal with comparing my UserAuthorities (roles).
When I send a GET request through postman and authorize with a username and password, my user is found (I do not get a 401), but I get a 403, as if the user did not have proper role. If I change (hasRole(Role.ADMIN.name()) to authenticated() it works great. Can you please take a look at my code and help me figure out what I am missing?
User class:

```<code>@Entity
@NoArgsConstructor
@Table(name = "users")
public class User implements UserDetails {
    @Id
    @GeneratedValue
    private Long id;
    @Column(nullable = false, unique = true)
    private String username;
    private String password;
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private Set<UserAuthority> authorities = new HashSet<UserAuthority>();

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public void addAuthority(UserAuthority authority) {
        authorities.add(authority);
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    public String getPassword() {
        return password;
    }

    public String getUsername() {
        return username;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isEnabled() {
        return true;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

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

    public void setAuthorities(Set<UserAuthority> authorities) {
        this.authorities = authorities;
    }
}
</code>```

UserAuthority class:

```<code>@Entity
@Table(name = "authorities")
@NoArgsConstructor
@Getter
@Setter
public class UserAuthority implements GrantedAuthority {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    public UserAuthority(String name) {
        this.name = name;
    }

    public String getAuthority() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserAuthority authority = (UserAuthority) o;

        return name != null ? name.equals(authority.name) : authority.name == null;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}
</code>```

Security configuration class:

```<code>@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static String REALM = "MY_TEST_REALM";
    //to be a bean later
    private PasswordEncoder passwordEncoder = new StandardPasswordEncoder();
    @Autowired
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/**").hasRole(Role.ADMIN.name())
                .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint())
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.
    }

    @Bean
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
        return new CustomBasicAuthenticationEntryPoint();
    }

    /* To allow Pre-flight [OPTIONS] request from browser */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
}
</code>```

Important part of UserServiceImpl class:

```<code>@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserAuthorityRepository userAuthorityRepository;
    private PasswordEncoder passwordEncoder = new StandardPasswordEncoder();

    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        return userRepository.getUserByUserName(s);
    }
}
</code>```

The response I get is 403: The server understood the request but refuses to authorize it.

userRepository.getUserByUserName(s) returns me a proper User object with the correct authorities.

I am sorry that there is so much code, I just do not have a clue where the mistake might possibly be..
Thank you very much for your help!
Cheers

答:
I solved it! Turns out the roles have to be persisted with a prefix "ROLE_", so I added this to my Role enum:

```<code>private static final String ROLE_PREFIX = "ROLE_";

public String nameWithPrefix() {
    return ROLE_PREFIX + name();
}
</code>```

Now it works :)

Body:
I have been trying to secure my Spring Rest API with Basic Auth using Spring Security. I want it to be configured so that users are stored in a database and that they have access to different endpoints depending on their role.
For simplicity, in the below example all endpoints require "ADMIN" role.
I think I configured everything correctly (based on some online tutorials), however it seems like Security cannot deal with comparing my UserAuthorities (roles).
When I send a GET request through postman and authorize with a username and password, my user is found (I do not get a 401), but I get a 403, as if the user did not have proper role. If I change (hasRole(Role.ADMIN.name()) to authenticated() it works great. Can you please take a look at my code and help me figure out what I am missing?
User class:

@Entity
@NoArgsConstructor
@Table(name = "users")
public class User implements UserDetails {
    @Id
    @GeneratedValue
    private Long id;
    @Column(nullable = false, unique = true)
    private String username;
    private String password;
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private Set<UserAuthority> authorities = new HashSet<UserAuthority>();

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public void addAuthority(UserAuthority authority) {
        authorities.add(authority);
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    public String getPassword() {
        return password;
    }

    public String getUsername() {
        return username;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isEnabled() {
        return true;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

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

    public void setAuthorities(Set<UserAuthority> authorities) {
        this.authorities = authorities;
    }
}

UserAuthority class:

@Entity
@Table(name = "authorities")
@NoArgsConstructor
@Getter
@Setter
public class UserAuthority implements GrantedAuthority {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    public UserAuthority(String name) {
        this.name = name;
    }

    public String getAuthority() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserAuthority authority = (UserAuthority) o;

        return name != null ? name.equals(authority.name) : authority.name == null;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}

Security configuration class:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static String REALM = "MY_TEST_REALM";
    //to be a bean later
    private PasswordEncoder passwordEncoder = new StandardPasswordEncoder();
    @Autowired
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/**").hasRole(Role.ADMIN.name())
                .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint())
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.
    }

    @Bean
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
        return new CustomBasicAuthenticationEntryPoint();
    }

    /* To allow Pre-flight [OPTIONS] request from browser */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
}

Important part of UserServiceImpl class:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserAuthorityRepository userAuthorityRepository;
    private PasswordEncoder passwordEncoder = new StandardPasswordEncoder();

    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        return userRepository.getUserByUserName(s);
    }
}

The response I get is 403: The server understood the request but refuses to authorize it.

userRepository.getUserByUserName(s) returns me a proper User object with the correct authorities.

I am sorry that there is so much code, I just do not have a clue where the mistake might possibly be..
Thank you very much for your help!
Cheers

Body:
I solved it! Turns out the roles have to be persisted with a prefix "ROLE_", so I added this to my Role enum:

private static final String ROLE_PREFIX = "ROLE_";

public String nameWithPrefix() {
    return ROLE_PREFIX + name();
}

Now it works :)


来源: stackexchange

问:
lmer returns error when run inside a function
I am trying to make a function that fits a mixed model on the chosen variable.

If I run this command inside the function:

```<code>lme4::lmer(VAR ~ cVAR + (1|ID), data=df)
</code>```

I get the error:

```<code>Error in model.frame.default(data = df, drop.unused.levels = TRUE, formula = VAR ~  :
  variable lengths differ (found for 'ID')
</code>```

I have tested my code in several ways, and I just cant find out whats wrong. I can make plots from inside the function without problems. If I try to just print the dataframe used inside the function it looks exactly as I want it to look.
Furthermore - If I run the lmer command outside the function (substituting VAR and cVAR for X and cX), the command runs without problems.

I therefore believe the error is caused by running lmer() inside the function. This Question has a similar problem, but is having a different error message than me.

Is there any way to run lmer inside a function without getting the error?

Reproducible example:

```<code>  set.seed(1)

org <- data.frame(
  X = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
  cX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
  Y = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
  cY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
  Frame = rep(1:5, 4),
  JN = rep(1:2, each=5),
  ID = rep(1:2, each=10))

FUNC <- function(VAR) {
  VAR <- deparse(substitute(VAR))
  cVAR <- paste0("c", VAR)
  df <- dplyr::select(org, ID, JN, Frame, VAR, cVAR) # Keeping only a subset of the data
  df <- df %>% tidyr::drop_na() #Keeping only complete cases

  stopifnot(all(c(VAR, cVAR) %in% names(df)))

  MixedModel <- lme4::lmer(VAR ~ cVAR + (1|ID), data=df)
  b <- plot(MixedModel)
}

#It works fine outside the function:
MixedModel_no_FUNC <- lme4::lmer(X ~ cX + (1|ID), data=org)
plot(MixedModel_no_FUNC)

#But not inside the function
FUNC(X)
</code>```

My sessionInfo in case it is relevant

```<code>R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=Danish_Denmark.1252  LC_CTYPE=Danish_Denmark.1252
[3] LC_MONETARY=Danish_Denmark.1252 LC_NUMERIC=C
[5] LC_TIME=Danish_Denmark.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
 [1] lme4_1.1-14          Matrix_1.2-10        ggExtra_0.7          BlandAltmanLeh_0.3.1
 [5] gganimate_0.1.0.9000 gridExtra_2.3        bindrcpp_0.2         dplyr_0.7.3
 [9] purrr_0.2.3          readr_1.1.1          tidyr_0.7.1          tibble_1.3.4
[13] tidyverse_1.1.1      ggmap_2.7            ggplot2_2.2.1

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.13      lubridate_1.6.0   lattice_0.20-35   png_0.1-7         assertthat_0.2.0
 [6] digest_0.6.12     psych_1.7.8       mime_0.5          R6_2.2.2          cellranger_1.1.0
[11] plyr_1.8.4        httr_1.3.1        RgoogleMaps_1.4.1 rlang_0.1.2       lazyeval_0.2.0
[16] readxl_1.0.0      minqa_1.2.4       geosphere_1.5-7   miniUI_0.1.1      nloptr_1.0.4
[21] splines_3.4.1     proto_1.0.0       labeling_0.3      stringr_1.2.0     foreign_0.8-69
[26] munsell_0.4.3     shiny_1.0.5       broom_0.4.2       compiler_3.4.1    httpuv_1.3.5
[31] modelr_0.1.1      pkgconfig_2.0.1   mnormt_1.5-5      htmltools_0.3.6   tidyselect_0.2.1
[36] MASS_7.3-47       bitops_1.0-6      grid_3.4.1        nlme_3.1-131      jsonlite_1.5
[41] xtable_1.8-2      gtable_0.2.0      magrittr_1.5      scales_0.5.0      stringi_1.1.5
[46] mapproj_1.2-5     reshape2_1.4.2    sp_1.2-5          xml2_1.1.1        rjson_0.2.15
[51] tools_3.4.1       forcats_0.2.0     glue_1.1.1        maps_3.2.0        hms_0.3
[56] jpeg_0.1-8        parallel_3.4.1    yaml_2.1.14       colorspace_1.3-2  rvest_0.3.2
[61] knitr_1.17        bindr_0.1         haven_1.1.0
</code>```

答:
You have some conflicting names of objects in your dataframe and the environment in your function. Here's your data:

```<code>org <- data.frame(
    X = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
    cX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
    Y = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
    cY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
    Frame = rep(1:5, 4),
    JN = rep(1:2, each=5),
    ID = rep(1:2, each=10))
</code>```

I choose to just pass a string to the VAR argument instead of deparsing like you did. Then check if VAR and cVAR are in the dataframe. Then I reduce the dataframe and rename VAR and cVAR to Y and X so that when you call lmer() you're sure that the formula is referring to the variables in the data.frame and not the objects in the function environment.

```<code>library(lme4)
FUNC <- function(VAR = "VAR", df) {
    cVAR <- paste0("c", VAR)
    stopifnot(all(c(VAR, cVAR) %in% names(df)))
    df <- df[,c("ID", "JN", "Frame", VAR, cVAR)]
    names(df) <- c(c("ID", "JN", "Frame", "Y", "X"))
    df <- df[complete.cases(df),]
    MixedModel <- lme4::lmer(Y ~ X + (1|ID), data=df)
    plot(MixedModel)
}

FUNC(VAR = "X", df = org)
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am trying to make a function that fits a mixed model on the chosen variable.

If I run this command inside the function:

lme4::lmer(VAR ~ cVAR + (1|ID), data=df)

I get the error:

Error in model.frame.default(data = df, drop.unused.levels = TRUE, formula = VAR ~  :
  variable lengths differ (found for 'ID')

I have tested my code in several ways, and I just cant find out whats wrong. I can make plots from inside the function without problems. If I try to just print the dataframe used inside the function it looks exactly as I want it to look.
Furthermore - If I run the lmer command outside the function (substituting VAR and cVAR for X and cX), the command runs without problems.

I therefore believe the error is caused by running lmer() inside the function. This Question has a similar problem, but is having a different error message than me.

Is there any way to run lmer inside a function without getting the error?

Reproducible example:

  set.seed(1)

org <- data.frame(
  X = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
  cX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
  Y = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
  cY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
  Frame = rep(1:5, 4),
  JN = rep(1:2, each=5),
  ID = rep(1:2, each=10))

FUNC <- function(VAR) {
  VAR <- deparse(substitute(VAR))
  cVAR <- paste0("c", VAR)
  df <- dplyr::select(org, ID, JN, Frame, VAR, cVAR) # Keeping only a subset of the data
  df <- df %>% tidyr::drop_na() #Keeping only complete cases

  stopifnot(all(c(VAR, cVAR) %in% names(df)))

  MixedModel <- lme4::lmer(VAR ~ cVAR + (1|ID), data=df)
  b <- plot(MixedModel)
}

#It works fine outside the function:
MixedModel_no_FUNC <- lme4::lmer(X ~ cX + (1|ID), data=org)
plot(MixedModel_no_FUNC)

#But not inside the function
FUNC(X)

My sessionInfo in case it is relevant

R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=Danish_Denmark.1252  LC_CTYPE=Danish_Denmark.1252
[3] LC_MONETARY=Danish_Denmark.1252 LC_NUMERIC=C
[5] LC_TIME=Danish_Denmark.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
 [1] lme4_1.1-14          Matrix_1.2-10        ggExtra_0.7          BlandAltmanLeh_0.3.1
 [5] gganimate_0.1.0.9000 gridExtra_2.3        bindrcpp_0.2         dplyr_0.7.3
 [9] purrr_0.2.3          readr_1.1.1          tidyr_0.7.1          tibble_1.3.4
[13] tidyverse_1.1.1      ggmap_2.7            ggplot2_2.2.1

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.13      lubridate_1.6.0   lattice_0.20-35   png_0.1-7         assertthat_0.2.0
 [6] digest_0.6.12     psych_1.7.8       mime_0.5          R6_2.2.2          cellranger_1.1.0
[11] plyr_1.8.4        httr_1.3.1        RgoogleMaps_1.4.1 rlang_0.1.2       lazyeval_0.2.0
[16] readxl_1.0.0      minqa_1.2.4       geosphere_1.5-7   miniUI_0.1.1      nloptr_1.0.4
[21] splines_3.4.1     proto_1.0.0       labeling_0.3      stringr_1.2.0     foreign_0.8-69
[26] munsell_0.4.3     shiny_1.0.5       broom_0.4.2       compiler_3.4.1    httpuv_1.3.5
[31] modelr_0.1.1      pkgconfig_2.0.1   mnormt_1.5-5      htmltools_0.3.6   tidyselect_0.2.1
[36] MASS_7.3-47       bitops_1.0-6      grid_3.4.1        nlme_3.1-131      jsonlite_1.5
[41] xtable_1.8-2      gtable_0.2.0      magrittr_1.5      scales_0.5.0      stringi_1.1.5
[46] mapproj_1.2-5     reshape2_1.4.2    sp_1.2-5          xml2_1.1.1        rjson_0.2.15
[51] tools_3.4.1       forcats_0.2.0     glue_1.1.1        maps_3.2.0        hms_0.3
[56] jpeg_0.1-8        parallel_3.4.1    yaml_2.1.14       colorspace_1.3-2  rvest_0.3.2
[61] knitr_1.17        bindr_0.1         haven_1.1.0

Body:
You have some conflicting names of objects in your dataframe and the environment in your function. Here's your data:

org <- data.frame(
    X = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
    cX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
    Y = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
    cY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
    Frame = rep(1:5, 4),
    JN = rep(1:2, each=5),
    ID = rep(1:2, each=10))

I choose to just pass a string to the VAR argument instead of deparsing like you did. Then check if VAR and cVAR are in the dataframe. Then I reduce the dataframe and rename VAR and cVAR to Y and X so that when you call lmer() you're sure that the formula is referring to the variables in the data.frame and not the objects in the function environment.

library(lme4)
FUNC <- function(VAR = "VAR", df) {
    cVAR <- paste0("c", VAR)
    stopifnot(all(c(VAR, cVAR) %in% names(df)))
    df <- df[,c("ID", "JN", "Frame", VAR, cVAR)]
    names(df) <- c(c("ID", "JN", "Frame", "Y", "X"))
    df <- df[complete.cases(df),]
    MixedModel <- lme4::lmer(Y ~ X + (1|ID), data=df)
    plot(MixedModel)
}

FUNC(VAR = "X", df = org)


问:
Two times inherited from a generic class
I have two class

```<code>public class Singleton<T> : MonoBehaviour   where T : Component
{
    protected static T _instance;

    public static T Instance
    {
        get
        {
            return _instance;
        }
    }
}
</code>```

and

```<code>public class GameManager : Singleton<GameManager>
{
    // Lots of Methods and Properties...
}
</code>```

I want to create 3. class derived from GameManager for example ShooterGameManager. I can create ShooterGameManager with

```<code>public class ShooterGameManager : GameManager
{}
</code>```

but Instance is still GameManager !!!,
I tried something like to added extra class definition with generic class.

```<code>public class GameManager<T> : Singleton<T> where T : Component
{}
</code>```

but this time there are 2 completely different classes available, nothing inherited from GameManager. What should I do ???

答:
You could Create GameManager like this

```<code>public GameManger<T> : Singleton<T>
{}
</code>```

then you could create GameManger

```<code>public GameManager : GameManager<GameManger>
{}
</code>```

and ShooterGameManager

```<code>public ShooterGameManager : GameManager<ShooterGameManager>
{}
</code>```

and repeat for the other two types you need to create

an example below proves this works

```<code>public class Program
{
    public static void Main()
    {
        new GameManager(); //Prints GameManager
        new ShooterGameManager(); //prints ShooterGameManager
    }

}

public class Singleton<T>
{
    private T _instance;

    public Singleton()
    {
        Console.WriteLine(typeof(T).Name);
    }
}

public class GameManager<T> : Singleton<T>
{
}

public class GameManager : GameManager<GameManager>
{
}

public class ShooterGameManager : GameManager<ShooterGameManager>
{
}
</code>```

Body:
I have two class

public class Singleton<T> : MonoBehaviour   where T : Component
{
    protected static T _instance;

    public static T Instance
    {
        get
        {
            return _instance;
        }
    }
}

and

public class GameManager : Singleton<GameManager>
{
    // Lots of Methods and Properties...
}

I want to create 3. class derived from GameManager for example ShooterGameManager. I can create ShooterGameManager with

public class ShooterGameManager : GameManager
{}

but Instance is still GameManager !!!,
I tried something like to added extra class definition with generic class.

public class GameManager<T> : Singleton<T> where T : Component
{}

but this time there are 2 completely different classes available, nothing inherited from GameManager. What should I do ???

Body:
You could Create GameManager like this

public GameManger<T> : Singleton<T>
{}

then you could create GameManger

public GameManager : GameManager<GameManger>
{}

and ShooterGameManager

public ShooterGameManager : GameManager<ShooterGameManager>
{}

and repeat for the other two types you need to create

an example below proves this works

public class Program
{
    public static void Main()
    {
        new GameManager(); //Prints GameManager
        new ShooterGameManager(); //prints ShooterGameManager
    }

}

public class Singleton<T>
{
    private T _instance;

    public Singleton()
    {
        Console.WriteLine(typeof(T).Name);
    }
}

public class GameManager<T> : Singleton<T>
{
}

public class GameManager : GameManager<GameManager>
{
}

public class ShooterGameManager : GameManager<ShooterGameManager>
{
}


问:
Redux state clear on page changes
I have react container which is connected to an 'items' reducer. By navigating to another page, such as user profile, I want to get the user's 'items' list from the server and change the state. The issue is, that if I navigate from the main page, the items state is already filled with data, then on the user page I see the old for couple of seconds until it is changed from the api call. I was thinking about creating new reducer for the userItems, but then, if I will navigate to another user page, I will see the previous userItems for couple of seconds.

The solution is to fetch the data and keep it only in the react component state? And not redux?

Thanks.

答:
@Morgan Danger Hall has the right idea in their answer.

Depending on how often you go back and forth between users, you may also want to consider keeping all of the items for all users in the items array, and then adding an activeUser attribute to your state with the id of the user currently being viewed. Then you would have the display component filter the items list by the activeUser.

This could help with performance if you end up going back and forth between users, as long as you are comfortable with cacheing the results from previous fetches.

Just make sure you understand how volatile your items list is. If it's a rapidly-changing list, you might not want to cache it at all!

Title: Redux state clear on page changes


问:
Cannot install psycopg2 Ubuntu
Trying to get a server ready for a django project and I'm running into some issues with setup for postgres.

I'm following this guide:
https://jee-appy.blogspot.com/2017/01/deply-django-with-nginx.html

And I'm at step 5:

Now, we need to configure postgreSQL so that it can communicate with our Django application. For this, install psycopg2 database
  adapter. But this adapter have some package dependencies, so first
  install them.

run:

(django_env) $ sudo apt-get install libpq-dev python3-dev

then...

(django_env) $ pip install psycopg2

I do that, and this point in the instructions, I get a "compilation failed" error.

I tried the solutions suggested in this stack exchange question:
Trouble with psycopg2 in virtualenv python3 for use with Django
and this one:
Cannot install psycopg2 on virtualenv

I am very much a linux and django noob, so if this is a duplicate issue, please have mercy on me and leave a comment explaining why you are marking it as a duplicate as you do so.

Thanks for your time!

Here's the output and install command that caused it:

```<code>(django_env1) user:/home/projects/sample_project$ sudo pip install psycopg2
Downloading/unpacking psycopg2
  Downloading psycopg2-2.7.3.2.tar.gz (425kB): 425kB downloaded
  Running setup.py (path:/tmp/pip_build_root/psycopg2/setup.py) egg_info for package psycopg2

Installing collected packages: psycopg2
  Running setup.py install for psycopg2
    building 'psycopg2._psycopg' extension
    x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.7.3.2 (dt dec pq3 ext lo64)" -DPG_VERSION_NUM=90320 -DHAVE_LO64=1 -I/usr/include/python2.7 -I. -I/usr/include/postgresql -I/usr/include/postgresql/9.3/server -c psycopg/psycopgmodule.c -o build/temp.linux-x86_64-2.7/psycopg/psycopgmodule.o -Wdeclaration-after-statement
    In file included from psycopg/psycopgmodule.c:27:0:
    ./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory
     #include <Python.h>
                        ^
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
    Complete output from command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip_build_root/psycopg2/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_0zc1L-record/install-record.txt --single-version-externally-managed --compile:
    running install

running build

running build_py

creating build

creating build/lib.linux-x86_64-2.7

creating build/lib.linux-x86_64-2.7/psycopg2

copying lib/_ipaddress.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/tz.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/_json.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/__init__.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/errorcodes.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/psycopg1.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/_range.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/extensions.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/sql.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/pool.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/extras.py -> build/lib.linux-x86_64-2.7/psycopg2

creating build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_bug_gc.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_psycopg2_dbapi20.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_types_extras.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_async_keyword.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_sql.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_ipaddress.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/dbapi20.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_fast_executemany.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/__init__.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_copy.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_with.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_connection.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_module.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_replication.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_extras_dictcursor.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_dates.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_bugX000.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/testconfig.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_errcodes.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_transaction.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_async.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/testutils.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_cursor.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_quote.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/dbapi20_tpc.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_notify.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_lobject.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_cancel.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_green.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_types_basic.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

running build_ext

building 'psycopg2._psycopg' extension

creating build/temp.linux-x86_64-2.7

creating build/temp.linux-x86_64-2.7/psycopg

x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.7.3.2 (dt dec pq3 ext lo64)" -DPG_VERSION_NUM=90320 -DHAVE_LO64=1 -I/usr/include/python2.7 -I. -I/usr/include/postgresql -I/usr/include/postgresql/9.3/server -c psycopg/psycopgmodule.c -o build/temp.linux-x86_64-2.7/psycopg/psycopgmodule.o -Wdeclaration-after-statement

In file included from psycopg/psycopgmodule.c:27:0:

./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory

 #include <Python.h>

                    ^

compilation terminated.

error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

----------------------------------------
Cleaning up...
Command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip_build_root/psycopg2/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_0zc1L-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /tmp/pip_build_root/psycopg2
</code>```

答:
You've installed the python-dev libraries for Python 3. Your psycopg2 install is using python 2.7

If you want to use Python 3:

Make sure you've installed python3-pip

```<code>sudo apt-get install python3-pip
</code>```

Then:

```<code>pip3 install psycopg2
</code>```

If that still fails, try installing the development headers for postgresql:

```<code>sudo apt install python3-dev libpq-dev
pip3 install psycopg2
</code>```

If on Python 2

```<code>sudo apt update
sudo apt-get install postgresql postgresql-contrib
sudo apt-get install libpq-dev
sudo apt-get install python-dev
sudo apt-get install python-pip
pip2 install psycopg2-binary
</code>```

If on Ubuntu 20.04 or above

```<code>sudo apt-get install build-essential
</code>```

Then run the other steps for either Python 2 or 3.

Title: Cannot install psycopg2 Ubuntu

Body:
Trying to get a server ready for a django project and I'm running into some issues with setup for postgres.

I'm following this guide:
https://jee-appy.blogspot.com/2017/01/deply-django-with-nginx.html

And I'm at step 5:

Now, we need to configure postgreSQL so that it can communicate with our Django application. For this, install psycopg2 database
  adapter. But this adapter have some package dependencies, so first
  install them.

run:

(django_env) $ sudo apt-get install libpq-dev python3-dev

then...

(django_env) $ pip install psycopg2

I do that, and this point in the instructions, I get a "compilation failed" error.

I tried the solutions suggested in this stack exchange question:
Trouble with psycopg2 in virtualenv python3 for use with Django
and this one:
Cannot install psycopg2 on virtualenv

I am very much a linux and django noob, so if this is a duplicate issue, please have mercy on me and leave a comment explaining why you are marking it as a duplicate as you do so.

Thanks for your time!

Here's the output and install command that caused it:

(django_env1) user:/home/projects/sample_project$ sudo pip install psycopg2
Downloading/unpacking psycopg2
  Downloading psycopg2-2.7.3.2.tar.gz (425kB): 425kB downloaded
  Running setup.py (path:/tmp/pip_build_root/psycopg2/setup.py) egg_info for package psycopg2

Installing collected packages: psycopg2
  Running setup.py install for psycopg2
    building 'psycopg2._psycopg' extension
    x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.7.3.2 (dt dec pq3 ext lo64)" -DPG_VERSION_NUM=90320 -DHAVE_LO64=1 -I/usr/include/python2.7 -I. -I/usr/include/postgresql -I/usr/include/postgresql/9.3/server -c psycopg/psycopgmodule.c -o build/temp.linux-x86_64-2.7/psycopg/psycopgmodule.o -Wdeclaration-after-statement
    In file included from psycopg/psycopgmodule.c:27:0:
    ./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory
     #include <Python.h>
                        ^
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
    Complete output from command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip_build_root/psycopg2/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_0zc1L-record/install-record.txt --single-version-externally-managed --compile:
    running install

running build

running build_py

creating build

creating build/lib.linux-x86_64-2.7

creating build/lib.linux-x86_64-2.7/psycopg2

copying lib/_ipaddress.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/tz.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/_json.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/__init__.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/errorcodes.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/psycopg1.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/_range.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/extensions.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/sql.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/pool.py -> build/lib.linux-x86_64-2.7/psycopg2

copying lib/extras.py -> build/lib.linux-x86_64-2.7/psycopg2

creating build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_bug_gc.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_psycopg2_dbapi20.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_types_extras.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_async_keyword.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_sql.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_ipaddress.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/dbapi20.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_fast_executemany.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/__init__.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_copy.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_with.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_connection.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_module.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_replication.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_extras_dictcursor.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_dates.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_bugX000.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/testconfig.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_errcodes.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_transaction.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_async.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/testutils.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_cursor.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_quote.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/dbapi20_tpc.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_notify.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_lobject.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_cancel.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_green.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

copying tests/test_types_basic.py -> build/lib.linux-x86_64-2.7/psycopg2/tests

running build_ext

building 'psycopg2._psycopg' extension

creating build/temp.linux-x86_64-2.7

creating build/temp.linux-x86_64-2.7/psycopg

x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DPSYCOPG_DEFAULT_PYDATETIME=1 -DPSYCOPG_VERSION="2.7.3.2 (dt dec pq3 ext lo64)" -DPG_VERSION_NUM=90320 -DHAVE_LO64=1 -I/usr/include/python2.7 -I. -I/usr/include/postgresql -I/usr/include/postgresql/9.3/server -c psycopg/psycopgmodule.c -o build/temp.linux-x86_64-2.7/psycopg/psycopgmodule.o -Wdeclaration-after-statement

In file included from psycopg/psycopgmodule.c:27:0:

./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory

 #include <Python.h>

                    ^

compilation terminated.

error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

----------------------------------------
Cleaning up...
Command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip_build_root/psycopg2/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_0zc1L-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /tmp/pip_build_root/psycopg2

Body:
You've installed the python-dev libraries for Python 3. Your psycopg2 install is using python 2.7

If you want to use Python 3:

Make sure you've installed python3-pip

sudo apt-get install python3-pip

Then:

pip3 install psycopg2

If that still fails, try installing the development headers for postgresql:

sudo apt install python3-dev libpq-dev
pip3 install psycopg2

If on Python 2

sudo apt update
sudo apt-get install postgresql postgresql-contrib
sudo apt-get install libpq-dev
sudo apt-get install python-dev
sudo apt-get install python-pip
pip2 install psycopg2-binary

If on Ubuntu 20.04 or above

sudo apt-get install build-essential

Then run the other steps for either Python 2 or 3.

ContentLicense: CC BY-SA 4.0


问:
While loop starts from beginning in tic tac toe game
I am trying to write a tic tac toe game with java. In this game there are two player as A and B. Player A always starts the game(X),
and Player B is (O). I used random method to generate move numbers.

So, I created a while loop but it always start from beginning but I want to print a new board with latest move.

There's code below if you look at it and say what is the point that I am missing I will be glad.

Also singular numbers are belong to player A, plurals are belong to player B
I have to add +1 to whoseTurn for correct move(if random method tries to write X or O to a position has already taken, it must generate another row and column number but I couldn't figure it out as well)

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

public class TicTacToe {

final static int SIZE = 5;
private static int row;
private static int column;

static Random number = new Random();
static char [][] array = new char[SIZE][SIZE];

public static void createBoard(){
    for(int i = 0; i < array.length; i++) {
        for(int j = 0; j < array.length; j++) {
            array[i][j] = '#';
        }
    }

    for(int i = 0; i < array.length; i++) {
        for(int j = 0; j < array.length; j++) {
            System.out.print(array[i][j] + " ");
        }
        System.out.println();
    }
    System.out.println();
    System.out.println("--------------");
}

public static void move(){
    int whoseTurn =1;
    while(whoseTurn <= (SIZE * SIZE)) {
        row = number.nextInt(6-1) + 1;
        column = number.nextInt(6-1) + 1;
        if ((whoseTurn % 2) != 0) {
            for(int i = 0; i < array.length; i++){
                for(int j = 0; j < array.length; j++){
                    array[i][j] = '#';
                    array[row-1][column-1] = 'X';
                }
            }
            for(int i = 0; i < array.length; i++){
                for(int j = 0; j < array.length; j++){
                    System.out.print(array[i][j] + " ");
                }
                System.out.println();
            }
            System.out.println("--------------");
            whoseTurn +=1;
        } else if((whoseTurn % 2) == 0){
            for(int i = 0; i < array.length; i++){
                for(int j = 0; j < array.length; j++){
                    array[i][j] = '#';
                    array[row-1][column-1] = 'O';
                    System.out.print(array[i][j] + " ");
                }
                System.out.println();
            }
            whoseTurn += 1;
        }
    }
}
</code>```

答:
You need to keep table state somewhere.

It could be done like this:

You create a Pair class that holds coordinates of the symbols:

```<code>public class Pair {

    private int x;
    private int y;

    public Pair() {}

    public Pair (int x, int y) {
        setX(x);
        setY(y);
    }

    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }

    public boolean equals(Pair pair) {
        return pair.getX() == this.x && pair.getY() == this.y ? true : false;
    }

}
</code>```

You then could then make your own ArrayList implementation that will make checking if the history already contains the coordinates much easier:

```<code>public class PairList extends ArrayList<Pair>{

    /**
     *
     */
    private static final long serialVersionUID = -7047628156984387721L;

    public boolean contains(int x, int y) {
        for (Pair pair : this) {
            if (pair.getX() == x && pair.getY() == y) {
                return true;
            }
        }
        return false;
    }

}
</code>```

And, finally your TicTacToe class would look something like this:

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

public class TicTacToe {

    final static int SIZE = 5;
    private static int row;
    private static int column;

    static Random number = new Random();
    static char[][] array = new char[SIZE][SIZE];

    public static void createBoard() {

        for (int i = 0; i < array.length; i++) {

            for (int j = 0; j < array.length; j++) {

                array[i][j] = '#';
            }

        }

        for (int i = 0; i < array.length; i++) {

            for (int j = 0; j < array.length; j++) {

                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println();
        System.out.println("--------------");
    }

    public static void move() {

        int whoseTurn = 1;

        PairList boardStatusX = new PairList();
        PairList boardStatusY = new PairList();

        while (whoseTurn <= (SIZE * SIZE)) {

            do {

                row = number.nextInt(6 - 1) + 1;

                column = number.nextInt(6 - 1) + 1;

            } while (boardStatusX.contains(row, column) || boardStatusY.contains(row, column));

            if ((whoseTurn % 2) != 0) {

                boardStatusX.add(new Pair(row, column));

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {

                        if (boardStatusX.contains(i, j)) {
                            array[i][j] = 'X';
                        }

                        else {
                            array[i][j] = '#';
                        }

                    }
                }

                //array[row - 1][column - 1] = 'X';

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {
                        System.out.print(array[i][j] + " ");
                    }

                    System.out.println();
                }
                System.out.println("--------------");

                whoseTurn += 1;
            }

            else if ((whoseTurn % 2) == 0) {
                boardStatusY.add(new Pair(row, column));

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {

                        if (boardStatusY.contains(i, j)) {
                            array[i][j] = 'Y';
                        }

                        else {
                            array[i][j] = '#';
                        }

                    }
                }

                //array[row - 1][column - 1] = 'Y';

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {
                        System.out.print(array[i][j] + " ");
                    }

                    System.out.println();
                }
                System.out.println("--------------");

                whoseTurn += 1;
            }

        }
    }
}
</code>```

Body:
I am trying to write a tic tac toe game with java. In this game there are two player as A and B. Player A always starts the game(X),
and Player B is (O). I used random method to generate move numbers.

So, I created a while loop but it always start from beginning but I want to print a new board with latest move.

There's code below if you look at it and say what is the point that I am missing I will be glad.

Also singular numbers are belong to player A, plurals are belong to player B
I have to add +1 to whoseTurn for correct move(if random method tries to write X or O to a position has already taken, it must generate another row and column number but I couldn't figure it out as well)

import java.util.Random;

public class TicTacToe {

final static int SIZE = 5;
private static int row;
private static int column;

static Random number = new Random();
static char [][] array = new char[SIZE][SIZE];

public static void createBoard(){
    for(int i = 0; i < array.length; i++) {
        for(int j = 0; j < array.length; j++) {
            array[i][j] = '#';
        }
    }

    for(int i = 0; i < array.length; i++) {
        for(int j = 0; j < array.length; j++) {
            System.out.print(array[i][j] + " ");
        }
        System.out.println();
    }
    System.out.println();
    System.out.println("--------------");
}

public static void move(){
    int whoseTurn =1;
    while(whoseTurn <= (SIZE * SIZE)) {
        row = number.nextInt(6-1) + 1;
        column = number.nextInt(6-1) + 1;
        if ((whoseTurn % 2) != 0) {
            for(int i = 0; i < array.length; i++){
                for(int j = 0; j < array.length; j++){
                    array[i][j] = '#';
                    array[row-1][column-1] = 'X';
                }
            }
            for(int i = 0; i < array.length; i++){
                for(int j = 0; j < array.length; j++){
                    System.out.print(array[i][j] + " ");
                }
                System.out.println();
            }
            System.out.println("--------------");
            whoseTurn +=1;
        } else if((whoseTurn % 2) == 0){
            for(int i = 0; i < array.length; i++){
                for(int j = 0; j < array.length; j++){
                    array[i][j] = '#';
                    array[row-1][column-1] = 'O';
                    System.out.print(array[i][j] + " ");
                }
                System.out.println();
            }
            whoseTurn += 1;
        }
    }
}

Body:
You need to keep table state somewhere.

It could be done like this:

You create a Pair class that holds coordinates of the symbols:

public class Pair {

    private int x;
    private int y;

    public Pair() {}

    public Pair (int x, int y) {
        setX(x);
        setY(y);
    }

    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }

    public boolean equals(Pair pair) {
        return pair.getX() == this.x && pair.getY() == this.y ? true : false;
    }

}

You then could then make your own ArrayList implementation that will make checking if the history already contains the coordinates much easier:

public class PairList extends ArrayList<Pair>{

    /**
     *
     */
    private static final long serialVersionUID = -7047628156984387721L;

    public boolean contains(int x, int y) {
        for (Pair pair : this) {
            if (pair.getX() == x && pair.getY() == y) {
                return true;
            }
        }
        return false;
    }

}

And, finally your TicTacToe class would look something like this:

import java.util.Random;

public class TicTacToe {

    final static int SIZE = 5;
    private static int row;
    private static int column;

    static Random number = new Random();
    static char[][] array = new char[SIZE][SIZE];

    public static void createBoard() {

        for (int i = 0; i < array.length; i++) {

            for (int j = 0; j < array.length; j++) {

                array[i][j] = '#';
            }

        }

        for (int i = 0; i < array.length; i++) {

            for (int j = 0; j < array.length; j++) {

                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println();
        System.out.println("--------------");
    }

    public static void move() {

        int whoseTurn = 1;

        PairList boardStatusX = new PairList();
        PairList boardStatusY = new PairList();

        while (whoseTurn <= (SIZE * SIZE)) {

            do {

                row = number.nextInt(6 - 1) + 1;

                column = number.nextInt(6 - 1) + 1;

            } while (boardStatusX.contains(row, column) || boardStatusY.contains(row, column));

            if ((whoseTurn % 2) != 0) {

                boardStatusX.add(new Pair(row, column));

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {

                        if (boardStatusX.contains(i, j)) {
                            array[i][j] = 'X';
                        }

                        else {
                            array[i][j] = '#';
                        }

                    }
                }

                //array[row - 1][column - 1] = 'X';

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {
                        System.out.print(array[i][j] + " ");
                    }

                    System.out.println();
                }
                System.out.println("--------------");

                whoseTurn += 1;
            }

            else if ((whoseTurn % 2) == 0) {
                boardStatusY.add(new Pair(row, column));

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {

                        if (boardStatusY.contains(i, j)) {
                            array[i][j] = 'Y';
                        }

                        else {
                            array[i][j] = '#';
                        }

                    }
                }

                //array[row - 1][column - 1] = 'Y';

                for (int i = 0; i < array.length; i++) {

                    for (int j = 0; j < array.length; j++) {
                        System.out.print(array[i][j] + " ");
                    }

                    System.out.println();
                }
                System.out.println("--------------");

                whoseTurn += 1;
            }

        }
    }
}


问:
Android - How to read txt file in JAVA
Please Will some one help me out i am trying to read an Arabic .txt file and it always give me the Arabic word like this "????? ???"</p>

```<code>private String ReadArabic() {

    String words="";
    try {
        InputStream stream = getAssets().open("arabwords.txt");

        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        words = new String(buffer, "UTF-8");
        words = words.replaceAll("(\\r|\\n)", "");
    } catch (IOException e) {
        // Handle exceptions here
    }
    return words;
}
</code>```

答:
it worked by using <strong>"cp1256"</strong>
Thanks Evey one </p>

```<code>private String ReadArabic() {

    String words="";
    try {
        InputStream stream = getAssets().open("arabwords.txt");

        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        words = new String(buffer, "cp1256");
        words = words.replaceAll("(\\r|\\n)", "");
    } catch (IOException e) {
        // Handle exceptions here
    }
    return words;
}
</code>```

Title: Android - How to read txt file in JAVA

Body:
Please Will some one help me out i am trying to read an Arabic .txt file and it always give me the Arabic word like this "????? ???"

private String ReadArabic() {

    String words="";
    try {
        InputStream stream = getAssets().open("arabwords.txt");

        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        words = new String(buffer, "UTF-8");
        words = words.replaceAll("(\\r|\\n)", "");
    } catch (IOException e) {
        // Handle exceptions here
    }
    return words;
}

Body:
it worked by using "cp1256"
Thanks Evey one

private String ReadArabic() {

    String words="";
    try {
        InputStream stream = getAssets().open("arabwords.txt");

        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        words = new String(buffer, "cp1256");
        words = words.replaceAll("(\\r|\\n)", "");
    } catch (IOException e) {
        // Handle exceptions here
    }
    return words;
}


问:
Environment variables with docker run -e
Here is my Dockerfile :

```<code>FROM ubuntu:16.04

RUN apt-get update

RUN apt-get install -y default-jdk

ADD sample-docker-1.0-SNAPSHOT.jar app.jar

EXPOSE 8080

ENV SITENAME="ASDASD"

ENTRYPOINT ["java", "-jar", "app.jar"]
</code>```

and here is a bit of Java code that i use:

```<code>@Value("${SITENAME:testsite}")
private String siteName;
</code>```

with this setup everything works good and environment value of SITENAME is indeed "ASDASD". But when i try to set that variable with:

```<code>docker run -P -d --name spring spring-app -e SITENAME='DOCKERlocal'
</code>```

it doesn't work (value is the one from Dockerfile). What am i missing here ?

答:
You want to pass the -e to the docker command. So:

```<code>docker run -P -d --name spring -e "SITENAME=DOCKERlocal" spring-app
</code>```

As you are doing it, you are passing it to the image entrypoint.

Body:
Here is my Dockerfile :

FROM ubuntu:16.04

RUN apt-get update

RUN apt-get install -y default-jdk

ADD sample-docker-1.0-SNAPSHOT.jar app.jar

EXPOSE 8080

ENV SITENAME="ASDASD"

ENTRYPOINT ["java", "-jar", "app.jar"]

and here is a bit of Java code that i use:

@Value("${SITENAME:testsite}")
private String siteName;

with this setup everything works good and environment value of SITENAME is indeed "ASDASD". But when i try to set that variable with:

docker run -P -d --name spring spring-app -e SITENAME='DOCKERlocal'

it doesn't work (value is the one from Dockerfile). What am i missing here ?

Body:
You want to pass the -e to the docker command. So:

docker run -P -d --name spring -e "SITENAME=DOCKERlocal" spring-app

As you are doing it, you are passing it to the image entrypoint.


问:
Apache Beam / Flink ExceptionInChainedStubException
I am using Apache Beam 2.0.0 and the FlinkRunner (scala 2.10) of the same version.  I am testing against an in-process Flink master (default configuration) with the FlinkRunner dependency apparently bringing in Flink 1.2.1 at runtime (looking at MVN dependency tree).

What is the best way to figure out what actually went wrong when there are "User exceptions"?  This is not a question about what I did wrong this time; but rather how to tell - in general- how to get more info out of either Beam or Flink.  Here is  stacktrace:

```<code>Exception in thread "main" java.lang.RuntimeException: Pipeline execution failed
at org.apache.beam.runners.flink.FlinkRunner.run(FlinkRunner.java:122)
at org.apache.beam.sdk.Pipeline.run(Pipeline.java:295)
at org.apache.beam.sdk.Pipeline.run(Pipeline.java:281)
at com.mapfit.flow.data.environment.MFEnvironment.run(MFEnvironment.java:70)
at com.mapfit.flow.main.Scratch.main(Scratch.java:35)
Caused by: org.apache.flink.runtime.client.JobExecutionException: Job execution failed.
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply$mcV$sp(JobManager.scala:910)
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply(JobManager.scala:853)
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply(JobManager.scala:853)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.apache.beam.sdk.util.UserCodeException: org.apache.flink.runtime.operators.chaining.ExceptionInChainedStubException
at org.apache.beam.sdk.util.UserCodeException.wrap(UserCodeException.java:36)
at org.apache.beam.sdk.transforms.MapElements$1$auxiliary$PCieS8xh.invokeProcessElement(Unknown Source)
at org.apache.beam.runners.core.SimpleDoFnRunner.invokeProcessElement(SimpleDoFnRunner.java:197)
at org.apache.beam.runners.core.SimpleDoFnRunner.processElement(SimpleDoFnRunner.java:158)
at org.apache.beam.runners.flink.metrics.DoFnRunnerWithMetricsUpdate.processElement(DoFnRunnerWithMetricsUpdate.java:65)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction.mapPartition(FlinkDoFnFunction.java:118)
at org.apache.flink.runtime.operators.MapPartitionDriver.run(MapPartitionDriver.java:103)
at org.apache.flink.runtime.operators.BatchTask.run(BatchTask.java:490)
at org.apache.flink.runtime.operators.BatchTask.invoke(BatchTask.java:355)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:665)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.flink.runtime.operators.chaining.ExceptionInChainedStubException
at org.apache.flink.runtime.operators.chaining.ChainedFlatMapDriver.collect(ChainedFlatMapDriver.java:82)
at org.apache.flink.runtime.operators.util.metrics.CountingCollector.collect(CountingCollector.java:35)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction$MultiDoFnOutputManager.output(FlinkDoFnFunction.java:165)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnContext.outputWindowedValue(SimpleDoFnRunner.java:355)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.output(SimpleDoFnRunner.java:629)
at org.apache.beam.sdk.transforms.MapElements$1.processElement(MapElements.java:122)
</code>```

Notice the complete lack of anything related to code I wrote (other than my call to pipeline.run()).

I downloaded the source code for each of my linked jars, and I stepped into the ChainedFlatMapDriver which threw an exception on line 82, and eventually ended up looking at an EOFException generated by a call in Java object serialization (my values use default Coder).  I thought I wan onto something, but it appears that the cause of the EOFException is in SimpleCollectingOutputView line 79, which is thrown a lot, and often swallowed as what appears to be routine execution for Flink.

Any pointers from anyone who knows how to get Flink to disclose failure information?

Found more information after debugging:

```<code>Just found more info after walking through more Flink code in the debugger: java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.requestBuffer(LocalBufferPool.java:168)
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.requestBufferBlocking(LocalBufferPool.java:138)
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.sendToTarget(RecordWriter.java:131)
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.emit(RecordWriter.java:88)
at org.apache.flink.runtime.operators.shipping.OutputCollector.collect(OutputCollector.java:65)
at org.apache.flink.runtime.operators.util.metrics.CountingCollector.collect(CountingCollector.java:35)
at org.apache.beam.runners.flink.translation.functions.FlinkMultiOutputPruningFunction.flatMap(FlinkMultiOutputPruningFunction.java:46)
at org.apache.beam.runners.flink.translation.functions.FlinkMultiOutputPruningFunction.flatMap(FlinkMultiOutputPruningFunction.java:30)
at org.apache.flink.runtime.operators.chaining.ChainedFlatMapDriver.collect(ChainedFlatMapDriver.java:80)
at org.apache.flink.runtime.operators.util.metrics.CountingCollector.collect(CountingCollector.java:35)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction$MultiDoFnOutputManager.output(FlinkDoFnFunction.java:165)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnContext.outputWindowedValue(SimpleDoFnRunner.java:355)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.output(SimpleDoFnRunner.java:629)
at org.apache.beam.sdk.transforms.MapElements$1.processElement(MapElements.java:122)
at org.apache.beam.sdk.transforms.MapElements$1$auxiliary$vuuNRtio.invokeProcessElement(Unknown Source)
at org.apache.beam.runners.core.SimpleDoFnRunner.invokeProcessElement(SimpleDoFnRunner.java:197)
at org.apache.beam.runners.core.SimpleDoFnRunner.processElement(SimpleDoFnRunner.java:158)
at org.apache.beam.runners.flink.metrics.DoFnRunnerWithMetricsUpdate.processElement(DoFnRunnerWithMetricsUpdate.java:65)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction.mapPartition(FlinkDoFnFunction.java:118)
at org.apache.flink.runtime.operators.MapPartitionDriver.run(MapPartitionDriver.java:103)
at org.apache.flink.runtime.operators.BatchTask.run(BatchTask.java:490)
at org.apache.flink.runtime.operators.BatchTask.invoke(BatchTask.java:355)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:665)
at java.lang.Thread.run(Thread.java:745)
</code>```

答:
Take a look at these two links :
EOFException related to memory segments during run of Beam pipeline on Flink

https://issues.apache.org/jira/browse/BEAM-2831

I used to see similar exceptions while running beam on flinkrunner on yarn. Proposed coder in the page of the issue helped.

Apart from that I suggest to use loggers extensively until your pipeline runs smoothly. In yarn logs can be retrieved with yarn logs command. Do not know about your case (in-process Flink master) but you should be able to write some logs I assume...

Body:
I am using Apache Beam 2.0.0 and the FlinkRunner (scala 2.10) of the same version.  I am testing against an in-process Flink master (default configuration) with the FlinkRunner dependency apparently bringing in Flink 1.2.1 at runtime (looking at MVN dependency tree).

What is the best way to figure out what actually went wrong when there are "User exceptions"?  This is not a question about what I did wrong this time; but rather how to tell - in general- how to get more info out of either Beam or Flink.  Here is  stacktrace:

Exception in thread "main" java.lang.RuntimeException: Pipeline execution failed
at org.apache.beam.runners.flink.FlinkRunner.run(FlinkRunner.java:122)
at org.apache.beam.sdk.Pipeline.run(Pipeline.java:295)
at org.apache.beam.sdk.Pipeline.run(Pipeline.java:281)
at com.mapfit.flow.data.environment.MFEnvironment.run(MFEnvironment.java:70)
at com.mapfit.flow.main.Scratch.main(Scratch.java:35)
Caused by: org.apache.flink.runtime.client.JobExecutionException: Job execution failed.
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply$mcV$sp(JobManager.scala:910)
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply(JobManager.scala:853)
at org.apache.flink.runtime.jobmanager.JobManager$$anonfun$handleMessage$1$$anonfun$applyOrElse$7.apply(JobManager.scala:853)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.apache.beam.sdk.util.UserCodeException: org.apache.flink.runtime.operators.chaining.ExceptionInChainedStubException
at org.apache.beam.sdk.util.UserCodeException.wrap(UserCodeException.java:36)
at org.apache.beam.sdk.transforms.MapElements$1$auxiliary$PCieS8xh.invokeProcessElement(Unknown Source)
at org.apache.beam.runners.core.SimpleDoFnRunner.invokeProcessElement(SimpleDoFnRunner.java:197)
at org.apache.beam.runners.core.SimpleDoFnRunner.processElement(SimpleDoFnRunner.java:158)
at org.apache.beam.runners.flink.metrics.DoFnRunnerWithMetricsUpdate.processElement(DoFnRunnerWithMetricsUpdate.java:65)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction.mapPartition(FlinkDoFnFunction.java:118)
at org.apache.flink.runtime.operators.MapPartitionDriver.run(MapPartitionDriver.java:103)
at org.apache.flink.runtime.operators.BatchTask.run(BatchTask.java:490)
at org.apache.flink.runtime.operators.BatchTask.invoke(BatchTask.java:355)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:665)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.flink.runtime.operators.chaining.ExceptionInChainedStubException
at org.apache.flink.runtime.operators.chaining.ChainedFlatMapDriver.collect(ChainedFlatMapDriver.java:82)
at org.apache.flink.runtime.operators.util.metrics.CountingCollector.collect(CountingCollector.java:35)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction$MultiDoFnOutputManager.output(FlinkDoFnFunction.java:165)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnContext.outputWindowedValue(SimpleDoFnRunner.java:355)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.output(SimpleDoFnRunner.java:629)
at org.apache.beam.sdk.transforms.MapElements$1.processElement(MapElements.java:122)

Notice the complete lack of anything related to code I wrote (other than my call to pipeline.run()).

I downloaded the source code for each of my linked jars, and I stepped into the ChainedFlatMapDriver which threw an exception on line 82, and eventually ended up looking at an EOFException generated by a call in Java object serialization (my values use default Coder).  I thought I wan onto something, but it appears that the cause of the EOFException is in SimpleCollectingOutputView line 79, which is thrown a lot, and often swallowed as what appears to be routine execution for Flink.

Any pointers from anyone who knows how to get Flink to disclose failure information?

Found more information after debugging:

Just found more info after walking through more Flink code in the debugger: java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.requestBuffer(LocalBufferPool.java:168)
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.requestBufferBlocking(LocalBufferPool.java:138)
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.sendToTarget(RecordWriter.java:131)
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.emit(RecordWriter.java:88)
at org.apache.flink.runtime.operators.shipping.OutputCollector.collect(OutputCollector.java:65)
at org.apache.flink.runtime.operators.util.metrics.CountingCollector.collect(CountingCollector.java:35)
at org.apache.beam.runners.flink.translation.functions.FlinkMultiOutputPruningFunction.flatMap(FlinkMultiOutputPruningFunction.java:46)
at org.apache.beam.runners.flink.translation.functions.FlinkMultiOutputPruningFunction.flatMap(FlinkMultiOutputPruningFunction.java:30)
at org.apache.flink.runtime.operators.chaining.ChainedFlatMapDriver.collect(ChainedFlatMapDriver.java:80)
at org.apache.flink.runtime.operators.util.metrics.CountingCollector.collect(CountingCollector.java:35)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction$MultiDoFnOutputManager.output(FlinkDoFnFunction.java:165)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnContext.outputWindowedValue(SimpleDoFnRunner.java:355)
at org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.output(SimpleDoFnRunner.java:629)
at org.apache.beam.sdk.transforms.MapElements$1.processElement(MapElements.java:122)
at org.apache.beam.sdk.transforms.MapElements$1$auxiliary$vuuNRtio.invokeProcessElement(Unknown Source)
at org.apache.beam.runners.core.SimpleDoFnRunner.invokeProcessElement(SimpleDoFnRunner.java:197)
at org.apache.beam.runners.core.SimpleDoFnRunner.processElement(SimpleDoFnRunner.java:158)
at org.apache.beam.runners.flink.metrics.DoFnRunnerWithMetricsUpdate.processElement(DoFnRunnerWithMetricsUpdate.java:65)
at org.apache.beam.runners.flink.translation.functions.FlinkDoFnFunction.mapPartition(FlinkDoFnFunction.java:118)
at org.apache.flink.runtime.operators.MapPartitionDriver.run(MapPartitionDriver.java:103)
at org.apache.flink.runtime.operators.BatchTask.run(BatchTask.java:490)
at org.apache.flink.runtime.operators.BatchTask.invoke(BatchTask.java:355)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:665)
at java.lang.Thread.run(Thread.java:745)


问:
Handling JSON response which sometimes doesn't have array
I am consuming some JSON in a C# console application and for some of the data, there is an array of options. Example JSON:

```<code>{
    "FIELD_NAME": "Survey",
    "VALUE": "",
    "FIELD_ID": 1234,
    "OPTIONS":[
        { "VALUE": "GENERAL", "DISPLAY_ORDER": 1, "DISPLAY": "GENERAL" },
        { "VALUE": "HPEFS",   "DISPLAY_ORDER": 3, "DISPLAY": "HPEFS" },
        { "VALUE": "NONE",    "DISPLAY_ORDER": 3, "DISPLAY": "NONE" }]
}
</code>```

But sometimes for records in the JSON the OPTIONS is empty:

```<code>{"FIELD_NAME":"Product_Node3","VALUE":"","FIELD_ID":1740,"OPTIONS":{}}
</code>```

As you can see the options is set to {} but it is my understanding that {} is an empty object, not an empty array.

When I try deserialize to a POCO I get an exception complaining that it requires a JSON array in the OPTIONS property.

My field class:

```<code>public class Field
{
    public string FIELD_NAME { get; set; }
    public string VALUE { get; set; }
    public int FIELD_ID { get; set; }
    public List<Option> OPTIONS { get; set;
    }
}
</code>```

And options class:

```<code>public class Option
{
    public string VALUE { get; set; }
    public int DISPLAY_ORDER { get; set; }
    public string DISPLAY { get; set; }
}
</code>```

The code which causes this exception is:

```<code>            var stringTest = File.ReadAllText("json.txt");
            var data = JsonConvert.DeserializeObject<List<Field>>(stringTest);
</code>```

Exception is:

```<code>Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[testproj.Option]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
</code>```

答:
Json.NET will throw an exception when the expected JSON value type (array, collection or primitive) does not match the observed value type.  Since, in the case of your List<Option> OPTIONS, you want unexpected value types to be skipped, you will need to create a custom JsonConverter such as the following:

```<code>public class TolerantCollectionConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        if (objectType.IsPrimitive || objectType == typeof(string) || objectType.IsArray)
            return false;
        return objectType.GetCollectionItemTypes().Count() == 1;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }
        else if (reader.TokenType == JsonToken.StartArray)
        {
            existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
            serializer.Populate(reader, existingValue);
            return existingValue;
        }
        else
        {
            reader.Skip();
            return existingValue;
        }
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public static class TypeExtensions
{
    /// <summary>
    /// Return all interfaces implemented by the incoming type as well as the type itself if it is an interface.
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static IEnumerable<Type> GetInterfacesAndSelf(this Type type)
    {
        if (type == null)
            throw new ArgumentNullException();
        if (type.IsInterface)
            return new[] { type }.Concat(type.GetInterfaces());
        else
            return type.GetInterfaces();
    }

    public static IEnumerable<Type> GetCollectionItemTypes(this Type type)
    {
        foreach (Type intType in type.GetInterfacesAndSelf())
        {
            if (intType.IsGenericType
                && intType.GetGenericTypeDefinition() == typeof(ICollection<>))
            {
                yield return intType.GetGenericArguments()[0];
            }
        }
    }
}
</code>```

Then apply it to Field as follows:

```<code>public class Field
{
    public string FIELD_NAME { get; set; }
    public string VALUE { get; set; }
    public int FIELD_ID { get; set; }

    [JsonConverter(typeof(TolerantCollectionConverter))]
    public List<Option> OPTIONS { get; set; }
}
</code>```

Or use it for all collections via JsonSerializerSettings:

```<code>var settings = new JsonSerializerSettings
{
    Converters = { new TolerantCollectionConverter() },
};
var obj = JsonConvert.DeserializeObject<Field>(stringTest, settings);
</code>```

Notes:

The converter only works for collections that are writable, since it allocates the collection first and then populates it.  For read-only collections or arrays you need to populate a List<T> first then allocate the read-only collection or array from it.

My assumption here is that you want to ignore an empty object when an array value is expected.  If instead you want to deserialize the object into a collection item then add that to the returned collection you could use SingleOrArrayConverter<T> from How to handle both a single item and an array for the same property using JSON.net.

The root JSON container shown in your question is an object -- an unordered set of name/value pairs that begins with { and ends with } -- rather than an array.  Thus you need to deserialize it as a Field not a List<Field>.

Sample fiddle.

Body:
I am consuming some JSON in a C# console application and for some of the data, there is an array of options. Example JSON:

{
    "FIELD_NAME": "Survey",
    "VALUE": "",
    "FIELD_ID": 1234,
    "OPTIONS":[
        { "VALUE": "GENERAL", "DISPLAY_ORDER": 1, "DISPLAY": "GENERAL" },
        { "VALUE": "HPEFS",   "DISPLAY_ORDER": 3, "DISPLAY": "HPEFS" },
        { "VALUE": "NONE",    "DISPLAY_ORDER": 3, "DISPLAY": "NONE" }]
}

But sometimes for records in the JSON the OPTIONS is empty:

{"FIELD_NAME":"Product_Node3","VALUE":"","FIELD_ID":1740,"OPTIONS":{}}

As you can see the options is set to {} but it is my understanding that {} is an empty object, not an empty array.

When I try deserialize to a POCO I get an exception complaining that it requires a JSON array in the OPTIONS property.

My field class:

public class Field
{
    public string FIELD_NAME { get; set; }
    public string VALUE { get; set; }
    public int FIELD_ID { get; set; }
    public List<Option> OPTIONS { get; set;
    }
}

And options class:

public class Option
{
    public string VALUE { get; set; }
    public int DISPLAY_ORDER { get; set; }
    public string DISPLAY { get; set; }
}

The code which causes this exception is:

            var stringTest = File.ReadAllText("json.txt");
            var data = JsonConvert.DeserializeObject<List<Field>>(stringTest);

Exception is:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[testproj.Option]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

Body:
Json.NET will throw an exception when the expected JSON value type (array, collection or primitive) does not match the observed value type.  Since, in the case of your List<Option> OPTIONS, you want unexpected value types to be skipped, you will need to create a custom JsonConverter such as the following:

public class TolerantCollectionConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        if (objectType.IsPrimitive || objectType == typeof(string) || objectType.IsArray)
            return false;
        return objectType.GetCollectionItemTypes().Count() == 1;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }
        else if (reader.TokenType == JsonToken.StartArray)
        {
            existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
            serializer.Populate(reader, existingValue);
            return existingValue;
        }
        else
        {
            reader.Skip();
            return existingValue;
        }
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public static class TypeExtensions
{
    /// <summary>
    /// Return all interfaces implemented by the incoming type as well as the type itself if it is an interface.
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static IEnumerable<Type> GetInterfacesAndSelf(this Type type)
    {
        if (type == null)
            throw new ArgumentNullException();
        if (type.IsInterface)
            return new[] { type }.Concat(type.GetInterfaces());
        else
            return type.GetInterfaces();
    }

    public static IEnumerable<Type> GetCollectionItemTypes(this Type type)
    {
        foreach (Type intType in type.GetInterfacesAndSelf())
        {
            if (intType.IsGenericType
                && intType.GetGenericTypeDefinition() == typeof(ICollection<>))
            {
                yield return intType.GetGenericArguments()[0];
            }
        }
    }
}

Then apply it to Field as follows:

public class Field
{
    public string FIELD_NAME { get; set; }
    public string VALUE { get; set; }
    public int FIELD_ID { get; set; }

    [JsonConverter(typeof(TolerantCollectionConverter))]
    public List<Option> OPTIONS { get; set; }
}

Or use it for all collections via JsonSerializerSettings:

var settings = new JsonSerializerSettings
{
    Converters = { new TolerantCollectionConverter() },
};
var obj = JsonConvert.DeserializeObject<Field>(stringTest, settings);

Notes:

The converter only works for collections that are writable, since it allocates the collection first and then populates it.  For read-only collections or arrays you need to populate a List<T> first then allocate the read-only collection or array from it.

My assumption here is that you want to ignore an empty object when an array value is expected.  If instead you want to deserialize the object into a collection item then add that to the returned collection you could use SingleOrArrayConverter<T> from How to handle both a single item and an array for the same property using JSON.net.

The root JSON container shown in your question is an object -- an unordered set of name/value pairs that begins with { and ends with } -- rather than an array.  Thus you need to deserialize it as a Field not a List<Field>.

Sample fiddle.


问:
UITextView: Automatically break line when reached a fixed width
I'm working on a view which holds a UITextView. Estimating the correct height for the content works just fine but when continuously typing the content grows horizontally over the border. Which looks like this:

Is there any handy solution which automatically breaks the line when reaching the, through auto layout, defined max width ?

答:
The solution I came up with is a pretty simple approach: </p>

```<code>func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    let size = textView.sizeThatFits(textView.frame.size)
    if size.width >= self.maxTextViewWidth {
        let subString = textView.text.suffix(1)
        textView.text.removeLast(1)
        textView.text.append(contentsOf: "\n" +  subString)
    }

    return true
}
</code>```

Body:
The solution I came up with is a pretty simple approach:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    let size = textView.sizeThatFits(textView.frame.size)
    if size.width >= self.maxTextViewWidth {
        let subString = textView.text.suffix(1)
        textView.text.removeLast(1)
        textView.text.append(contentsOf: "\n" +  subString)
    }

    return true
}


问:
Count minimum operations required to reach target number
I'm currently working on a function in JavaScript that takes an array of numbers, for example: [5, 10, 18, 25, 30] and then returns an array which contains the count of minimum operations required that it took to get from 0 to the target number, by only adding 1 or multiplying by 2.

For example, from the array, the number 5 would return 4 because you'd do 0 + 1 = 1 x 2 = 2 x 2 = 4 + 1 = 5.

If the array passed in was [5,5,5] the output array would be [4,4,4].

I've looked around at potential solutions to this problem, some of which used iteration and others recursion. I found an answer for a similar question here Code Review - Find sequence by adding 5 or multiplying by 3.

The only difference is this was adding 5 or multiplying by 2, and it starts from 1 as opposed to 0. I've attempted to adapt this solution to suit my needs, however, for some reason, the code will only ever add 1 and never times 2. So, for the input 5 I am returned with 0 + 1 = 1 + 1 = 2 + 1 = 3 + 1 = 4 + 1 = 5 which obviously isn't the shortest solution.

Eventually I do need this to return an array, as the input will also be an array, however I'm struggling to even get this adaptation of the above answer to work, just with taking a single integer as a parameter.

When I pass 5 into this function I am returned with 5 instead of the shortest solution which is 4, because it only ever adds 1.

The code I have at the moment is:

```<code>function findSequence(goal) {
  function find(start, history) {
    if (start == goal) {
      return history;
    }
    if (start > goal) {
      return null;
    }
    return find(start + 1, "(" + history + " + 1)") ||
             find(start * 2, "(" + history + " * 2)");
  }
  return find(0, "0");
}
</code>```

How can I make this work? I need to return the shortest sequence count to get from 0 to the target number by only adding 1 or multiplying 2

答:
This is probably easier to do in reverse. Start with your target and apply either a minus 1 or a divide by 2 until you hit zero. Once you've found that sequence, reverse it and use inverse ops (plus 1, times 2) to get back to your target.

function getNext(num) {
  if (num === 0) return "end"
  if (num % 2 === 1) return "minus"
  return "div"
}

function makeSequence(num, ls) {
    const next = getNext(num);
    if (next === "end") return ls;
    ls.push(next)

    if (next === "div") return makeSequence(num/2, ls);
    if (next === "minus") return makeSequence(num-1, ls);
}

function reverseSequence(sqn) {
    return sqn.reverse().map(x => x === "minus" ? "plus" : "times");
}

var sqn = makeSequence(5, []);
var reversedSqn = reverseSequence(sqn)

console.log("Takes", reversedSqn.length, "steps with target of 5");
console.log("Steps are:", reversedSqn);

var bigSqn = makeSequence(200, []);
var bigReversedSqn = reverseSequence(bigSqn);

console.log("Takes", bigReversedSqn.length, "steps with target of 200");
console.log("Steps are:", bigReversedSqn);```

Body:
I'm currently working on a function in JavaScript that takes an array of numbers, for example: [5, 10, 18, 25, 30] and then returns an array which contains the count of minimum operations required that it took to get from 0 to the target number, by only adding 1 or multiplying by 2.

For example, from the array, the number 5 would return 4 because you'd do 0 + 1 = 1 x 2 = 2 x 2 = 4 + 1 = 5.

If the array passed in was [5,5,5] the output array would be [4,4,4].

I've looked around at potential solutions to this problem, some of which used iteration and others recursion. I found an answer for a similar question here Code Review - Find sequence by adding 5 or multiplying by 3.

The only difference is this was adding 5 or multiplying by 2, and it starts from 1 as opposed to 0. I've attempted to adapt this solution to suit my needs, however, for some reason, the code will only ever add 1 and never times 2. So, for the input 5 I am returned with 0 + 1 = 1 + 1 = 2 + 1 = 3 + 1 = 4 + 1 = 5 which obviously isn't the shortest solution.

Eventually I do need this to return an array, as the input will also be an array, however I'm struggling to even get this adaptation of the above answer to work, just with taking a single integer as a parameter.

When I pass 5 into this function I am returned with 5 instead of the shortest solution which is 4, because it only ever adds 1.

The code I have at the moment is:

function findSequence(goal) {
  function find(start, history) {
    if (start == goal) {
      return history;
    }
    if (start > goal) {
      return null;
    }
    return find(start + 1, "(" + history + " + 1)") ||
             find(start * 2, "(" + history + " * 2)");
  }
  return find(0, "0");
}

How can I make this work? I need to return the shortest sequence count to get from 0 to the target number by only adding 1 or multiplying 2


问:
How to validate an IP address with regular expression in Objective-C?
How to validate an IP address in Objective-C?</p>

答:
Swift edition:</p>

```<code>func isIPAddressValid(ip: String) -> Bool {
    guard let utf8Str = (ip as NSString).utf8String else {
        return false
    }

    let utf8:UnsafePointer<Int8> = UnsafePointer(utf8Str)
    var success: Int32

    var dst: in_addr = in_addr()
    success = inet_pton(AF_INET, utf8, &dst)
    if (success != 1) {
        var dst6: in6_addr? = in6_addr()
        success = inet_pton(AF_INET6, utf8, &dst6);
    }

    return success == 1
}
</code>```

Body:
Swift edition:

func isIPAddressValid(ip: String) -> Bool {
    guard let utf8Str = (ip as NSString).utf8String else {
        return false
    }

    let utf8:UnsafePointer<Int8> = UnsafePointer(utf8Str)
    var success: Int32

    var dst: in_addr = in_addr()
    success = inet_pton(AF_INET, utf8, &dst)
    if (success != 1) {
        var dst6: in6_addr? = in6_addr()
        success = inet_pton(AF_INET6, utf8, &dst6);
    }

    return success == 1
}