问:
yytext accumulation problam in yacc and lex
I am trying to print an AST and printing an Identifier's actual name in the tree.
I am using lex and yacc.

For some reason yacc reads ahead all the tokens in a single row until ';' and this prevents me from using yytext to access an identifier's text value.

This is the lex file:

```<code>%{

%}

%%
"&&"      {return OP_AND;}
\"|"\"|"    {return OP_OR;}
!=      {return OP_NE;}
==      {return OP_EQ;}
>       {return OP_GT;}
>=      {return OP_GE;}
\<      {return OP_LT;}
\<=     {return OP_LE;}
!       {return OP_NOT;}
=       {return ASSIGN;}
\+      {return PLUS;}
\-      {return MINUS;}
\*      {return MULT;}
\/      {return DIV;}
\&      {return ADRS;}
\^      {return PTR_VAL;}
\;  {return SEMI;}
,   {return COMMA;}
\{  {return CURLY_O;}
\}  {return CURLY_C;}
\(  {return PAREN_O;}
\)  {return PAREN_C;}
\|      {return BAR;}
\[  {return SQR_O;}
\]  {return SQR_C;}
else      {return ELSE;}
if        {return IF;}
do      {return DO;}
for        {return FOR;}
bool   {return BOOL;}
void   {return VOID;}
int { return INT;}
charp   {return CHARP;}
intp   {return INTP;}
string   {return STRING;}
while       {return WHILE;}
true      {return TRUE_;}
false     {return FALSE_;}
return    {return RETURN;}
null        {return NULL_;}

0|[1-9][0-9]*           {return CONST_INT;}

[a-zA-Z][a-zA-Z0-9]*           { return IDENT;}

\'.\'       {return CONST_CHAR; }
\".*\"  {return CONST_STRING; }

\[\$([^\$]*\$+[^\]])*[^\$]*\$+\]    { /*comment*/}

[ \n\t]   { /* skip whitespace */}

.     {return ILLEAGAL;}

%%
</code>```

This is the yacc file:
* note that some of the rules are not completely ready but are not used by this input file and are not relevant to this case.

```<code>%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern char *  yytext;

typedef struct node
{
    char * token;
    struct node *b1;
    struct node *b2;
    struct node *b3;
    struct node *b4;
}node;
int yylex();
int yyerror();

struct node* mknode2(char* token,node* b1,node* b2);
struct node* mknode3(char* token,node*b1,node*b2,node*b3);
struct node* mknode4(char* token,node*b1,node*b2,node*b3,node*b4);
int printtree(node* tree);
#define YYSTYPE node*
%}

%token SEMI COMMA CURLY_O CURLY_C PAREN_O PAREN_C SQR_O SQR_C BAR
%token BOOL INT CHAR STRING INTP CHARP VOID
%token IF DO WHILE FOR RETURN
%token CONST_INT CONST_CHAR CONST_STRING NULL_ IDENT TRUE_ FALSE_
%token ILLEAGAL
%right ASSIGN
%left  OP_OR OP_AND OP_NE OP_EQ OP_GT OP_GE OP_LT OP_LE
%left  PLUS MINUS
%left  MULT DIV
%right OP_NOT
%right ADRS
%right PTR_VAL
%nonassoc LOWER_THAN_ELSE
%nonassoc ELSE
%start program

%%

program    : functions {printtree($1);}
           ;

functions  : functions function {$$ = mknode2("FUNC" ,$2,$1);}
           |    {$$ = NULL;}
           ;

function   : type id PAREN_O f_params PAREN_C CURLY_O body CURLY_C { $$ = mknode3($1,$2,$4,$7);}
           ;

body       : var_decls stmts ret_stmt {$$ = mknode3("BODY" ,$1 , $2 , $3);}
           ;

nest_block : stmts {$$=$1;}
       ;

f_params   : f_params_ {$$ = $1;}
           | {$$ = NULL;}
           ;

f_params_  : f_params_ COMMA param {$$ = mknode2("," , $3 , $1);}
           | param {$$ = $1;}
           ;

param      : type id {$$ = mknode2($1 , NULL , $2 );}
           ;

var_decls  : var_decls var_decl { $$ = mknode2("DECL" , $2 , $1);}
          | var_decls function {$$ = mknode2("DECL" , $2 , $1);}
           | {$$ = NULL;}
           ;

var_decl   : type var_list SEMI { $$ = mknode2($1 , NULL , $2); }
           ;

var_list   : var_list COMMA dec_assign {$$ = mknode2(",", $3 , $1);}
           | dec_assign { $$ = $1 ;}
           ;

dec_assign : id ASSIGN expr { $$ = mknode2("=", $1 , $3);}
           | id {$$ = $1; }
           ;

type       : BOOL {$$ = yytexy;}
           | INT { $$ = yytext;}
           | CHAR {$$ = yytext;}
           | INTP {$$ = yytext;}
           | CHARP {$$ = yytext;}
           | STRING {$$ = yytext;}
           | VOID {$$ = yytext;}
           ;

stmts      : stmts stmt { $$ = mknode2("STMT" , $2 , $1 );}
           | { $$ = NULL ;}
           ;

stmt       : assignment SEMI {$$ = $1 ;}
           | fct_call   SEMI    {$$ = $1; }
           | IF PAREN_O expr PAREN_C opt_nest   %prec LOWER_THAN_ELSE {$$ = mknode2("if" , $3 , $5 );}
           | IF PAREN_O expr PAREN_C opt_nest ELSE opt_nest {$$ = mknode3("if" , $3 ,  $5 , $7 );}
           | WHILE PAREN_O expr PAREN_C opt_nest {$$ = mknode2("while" , $3 , $5);}
           | DO CURLY_O nest_block CURLY_C WHILE PAREN_O expr PAREN_C SEMI {$$ = mknode2("do" , $3 , $7);}
           | FOR PAREN_O assignment SEMI expr SEMI assignment PAREN_C opt_nest {$$ = mknode4("for" , $3 , $5 , $7 , $9 );}
           ;

opt_nest   : CURLY_O nest_block CURLY_C {$$ = $2;}
           | stmt {$$ = $1;}
           ;

ret_stmt   : RETURN expr SEMI { $$ = mknode2("return" , NULL , $2);}
        | { $$ = NULL; }
           ;

assignment : id ASSIGN expr {$$ = mknode2("=" , $1, $3);}
          | id SQR_O expr SQR_C ASSIGN expr {$$ = mknode3("=" , $1 , $3, $6 );}
           ;

fct_call   : id PAREN_O expr_list PAREN_C {$$ = mknode2("FUNCALL" , $1 ,$3 );}
           ;

expr_list  : expr_list_ expr {$$ = mknode2("AGRS" , $2 , $1);}
       | {$$ = NULL;}
       ;

expr_list_ : expr_list_ expr COMMA { $$ = mknode2("," , $2 , $1);}
       | {$$ = NULL;}
       ;

id         : IDENT { $$ = mknode2(strdup(yytext) , NULL , NULL);}
           ;

expr       : expr PLUS expr { $$ = mknode2("+" , $1 , $3);}
           | expr MINUS expr { $$ = mknode2("-" , $1 , $3);}
           | expr MULT expr { $$ = mknode2("*" , $1 , $3);}
           | expr DIV expr { $$ = mknode2("/" , $1 , $3);}
           | expr OP_AND expr { $$ = mknode2("&&" , $1 , $3);}
           | expr OP_OR expr { $$ = mknode2("||" , $1 , $3);}
           | expr OP_NE expr { $$ = mknode2("!=" , $1 , $3);}
           | expr OP_EQ expr {$$=mknode2("==",$1,$3);}
           | expr OP_GT expr {$$=mknode2(">",$1,$3);}
           | expr OP_GE expr {$$=mknode2(">=",$1,$3);}
           | expr OP_LT expr {$$=mknode2("<",$1,$3);}
           | expr OP_LE expr {$$=mknode2("<=",$1,$3);}
           | OP_NOT expr {$$=mknode2("!",NULL,$2);}
           | PTR_VAL expr {$$=mknode2("^",NULL,$2);}
           | ADRS expr  {$$=mknode2("&",NULL,$2);}
           | MINUS expr {$$=mknode2("-",NULL,$2);}
           | literal {$$=mknode2($1,NULL,NULL);}
           | fct_call {$$= $1 ;}
           | id {$$= $1;}
           | PAREN_O expr PAREN_C {$$=mknode2("(_)",NULL,$2);}
           | BAR expr BAR {$$=mknode2("|_|",NULL,$2);}
           ;

literal    : CONST_INT {$$ = "const_int";}
           | TRUE_ { $$ = "true" ;}
           | FALSE_ { $$ = "false" ;}
           | CONST_CHAR { $$ = "const_char" ;}
           | CONST_STRING { $$ = "const_string" ;}
           | NULL_ { $$ = "null" ;}
           ;

%%
#include "lex.yy.c"
void main(){
    return yyparse();
}

int tabCount =0;

struct node* mknode2(char* token,node*b1,node*b2)
{

    node* newnode=(node*)malloc(sizeof(node));
    char* newstr;

    if( token ){
        printf("token: %s \n" , token);
        newstr=(char*)malloc(sizeof(token)+1);
        newstr[sizeof(token)]='\0';
        strcpy(newstr,token);
    }
    else{

        newstr=(char*)malloc(3);
        strcpy(newstr,"AA");
    }

    newnode->b1=b1;
    newnode->b2=b2;
    newnode->b3=NULL;
    newnode->b4=NULL;
    newnode->token=newstr;

    return newnode;
}

struct node* mknode3(char* token,node*b1,node*b2,node*b3)
{
    node* newnode= mknode2(token,b1,b2);
    newnode->b3=b3;
    return newnode;
}

struct node* mknode4(char* token,node*b1,node*b2,node*b3,node*b4)
{
    node* newnode= mknode3(token,b1,b2,b3);
    newnode->b4=b4;
    return newnode;
}

void printTabs(){
    int i;
    for(i=0;i<tabCount;i++){
        printf("\t");
    }
}

int printtree(node* tree)
{

    tabCount++;
    printTabs();
    printf("%s\n",tree->token);

    if(tree->b1)printtree(tree->b1);
    if(tree->b2)printtree(tree->b2);
    if(tree->b3)printtree(tree->b3);
    if(tree->b4)printtree(tree->b4);

    tabCount--;
    return 1;
}

int yyerror(){
    printf("ERROR!\n");
    return 0;
}
</code>```

this is the input file:

```<code>void main(int x){
    int y,w,r; int z;
}
</code>```

this is the output AST in preorder:

```<code>FUNC
    void
        main
        int x
            x
        BODY
            DECL
                int z;
                    ;
                DECL
                    int y,w,r;
                        ,
                            ;
                            ,
                                ,
                                ,
</code>```

the output i expected:

```<code>FUNC
    void
        main
        int
            x
        BODY
            DECL
                int
                    z
                DECL
                    int
                        ,
                            y
                            ,
                                w
                                r
</code>```

As can be seen when I get to the rule: type in my yacc file yytext contains the whole sentence ("int y,w,r;" instead of just "int") and when I get to the rule: id it only contain one token, that happens to be one token forward then the expected token.

- Note that in the function name and the function arguments yytext works properly.

- I tried printing yytext from the lex file and the tokens seems to contain right values.

答:
yytext points to the last lexeme scanned. Any other previously-saved pointer into the scanner's intrrnal buffer (such as a previous value of yytext) is invalid, and xannot be assumed to point at anything useful.

In a parser action, you have really very little idea what the last token scanned is. Yacc/bison generate LALR(1) parsers, where the 1 indicates "one lookahead token". That means that the parser (can) always examine the next token, and if it does so that is the token yytext will point at. Some implementations always read ahead; others, like bison, sometimes do not read ahead if the lookahead won't change parser behaviour. So which token yytext points at during a parser action is unspecified and may change in future versions or with different implementations.

Bottom line: Never use yytext in a parser action. And never pass the pointer value of yytext from the scanner to the parser. If you will need the string value of the token in the parser, make a copy of the string and pass the address of the copy to the parser through yylval. If you use strdup or similar, don't forget to free the copy when you no longer need it.

Body:
I am trying to print an AST and printing an Identifier's actual name in the tree.
I am using lex and yacc.

For some reason yacc reads ahead all the tokens in a single row until ';' and this prevents me from using yytext to access an identifier's text value.

This is the lex file:

%{

%}

%%
"&&"      {return OP_AND;}
\"|"\"|"    {return OP_OR;}
!=      {return OP_NE;}
==      {return OP_EQ;}
>       {return OP_GT;}
>=      {return OP_GE;}
\<      {return OP_LT;}
\<=     {return OP_LE;}
!       {return OP_NOT;}
=       {return ASSIGN;}
\+      {return PLUS;}
\-      {return MINUS;}
\*      {return MULT;}
\/      {return DIV;}
\&      {return ADRS;}
\^      {return PTR_VAL;}
\;  {return SEMI;}
,   {return COMMA;}
\{  {return CURLY_O;}
\}  {return CURLY_C;}
\(  {return PAREN_O;}
\)  {return PAREN_C;}
\|      {return BAR;}
\[  {return SQR_O;}
\]  {return SQR_C;}
else      {return ELSE;}
if        {return IF;}
do      {return DO;}
for        {return FOR;}
bool   {return BOOL;}
void   {return VOID;}
int { return INT;}
charp   {return CHARP;}
intp   {return INTP;}
string   {return STRING;}
while       {return WHILE;}
true      {return TRUE_;}
false     {return FALSE_;}
return    {return RETURN;}
null        {return NULL_;}

0|[1-9][0-9]*           {return CONST_INT;}

[a-zA-Z][a-zA-Z0-9]*           { return IDENT;}

\'.\'       {return CONST_CHAR; }
\".*\"  {return CONST_STRING; }

\[\$([^\$]*\$+[^\]])*[^\$]*\$+\]    { /*comment*/}

[ \n\t]   { /* skip whitespace */}

.     {return ILLEAGAL;}

%%

This is the yacc file:
* note that some of the rules are not completely ready but are not used by this input file and are not relevant to this case.

%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern char *  yytext;

typedef struct node
{
    char * token;
    struct node *b1;
    struct node *b2;
    struct node *b3;
    struct node *b4;
}node;
int yylex();
int yyerror();

struct node* mknode2(char* token,node* b1,node* b2);
struct node* mknode3(char* token,node*b1,node*b2,node*b3);
struct node* mknode4(char* token,node*b1,node*b2,node*b3,node*b4);
int printtree(node* tree);
#define YYSTYPE node*
%}

%token SEMI COMMA CURLY_O CURLY_C PAREN_O PAREN_C SQR_O SQR_C BAR
%token BOOL INT CHAR STRING INTP CHARP VOID
%token IF DO WHILE FOR RETURN
%token CONST_INT CONST_CHAR CONST_STRING NULL_ IDENT TRUE_ FALSE_
%token ILLEAGAL
%right ASSIGN
%left  OP_OR OP_AND OP_NE OP_EQ OP_GT OP_GE OP_LT OP_LE
%left  PLUS MINUS
%left  MULT DIV
%right OP_NOT
%right ADRS
%right PTR_VAL
%nonassoc LOWER_THAN_ELSE
%nonassoc ELSE
%start program

%%

program    : functions {printtree($1);}
           ;

functions  : functions function {$$ = mknode2("FUNC" ,$2,$1);}
           |    {$$ = NULL;}
           ;

function   : type id PAREN_O f_params PAREN_C CURLY_O body CURLY_C { $$ = mknode3($1,$2,$4,$7);}
           ;

body       : var_decls stmts ret_stmt {$$ = mknode3("BODY" ,$1 , $2 , $3);}
           ;

nest_block : stmts {$$=$1;}
       ;

f_params   : f_params_ {$$ = $1;}
           | {$$ = NULL;}
           ;

f_params_  : f_params_ COMMA param {$$ = mknode2("," , $3 , $1);}
           | param {$$ = $1;}
           ;

param      : type id {$$ = mknode2($1 , NULL , $2 );}
           ;

var_decls  : var_decls var_decl { $$ = mknode2("DECL" , $2 , $1);}
          | var_decls function {$$ = mknode2("DECL" , $2 , $1);}
           | {$$ = NULL;}
           ;

var_decl   : type var_list SEMI { $$ = mknode2($1 , NULL , $2); }
           ;

var_list   : var_list COMMA dec_assign {$$ = mknode2(",", $3 , $1);}
           | dec_assign { $$ = $1 ;}
           ;

dec_assign : id ASSIGN expr { $$ = mknode2("=", $1 , $3);}
           | id {$$ = $1; }
           ;

type       : BOOL {$$ = yytexy;}
           | INT { $$ = yytext;}
           | CHAR {$$ = yytext;}
           | INTP {$$ = yytext;}
           | CHARP {$$ = yytext;}
           | STRING {$$ = yytext;}
           | VOID {$$ = yytext;}
           ;

stmts      : stmts stmt { $$ = mknode2("STMT" , $2 , $1 );}
           | { $$ = NULL ;}
           ;

stmt       : assignment SEMI {$$ = $1 ;}
           | fct_call   SEMI    {$$ = $1; }
           | IF PAREN_O expr PAREN_C opt_nest   %prec LOWER_THAN_ELSE {$$ = mknode2("if" , $3 , $5 );}
           | IF PAREN_O expr PAREN_C opt_nest ELSE opt_nest {$$ = mknode3("if" , $3 ,  $5 , $7 );}
           | WHILE PAREN_O expr PAREN_C opt_nest {$$ = mknode2("while" , $3 , $5);}
           | DO CURLY_O nest_block CURLY_C WHILE PAREN_O expr PAREN_C SEMI {$$ = mknode2("do" , $3 , $7);}
           | FOR PAREN_O assignment SEMI expr SEMI assignment PAREN_C opt_nest {$$ = mknode4("for" , $3 , $5 , $7 , $9 );}
           ;

opt_nest   : CURLY_O nest_block CURLY_C {$$ = $2;}
           | stmt {$$ = $1;}
           ;

ret_stmt   : RETURN expr SEMI { $$ = mknode2("return" , NULL , $2);}
        | { $$ = NULL; }
           ;

assignment : id ASSIGN expr {$$ = mknode2("=" , $1, $3);}
          | id SQR_O expr SQR_C ASSIGN expr {$$ = mknode3("=" , $1 , $3, $6 );}
           ;

fct_call   : id PAREN_O expr_list PAREN_C {$$ = mknode2("FUNCALL" , $1 ,$3 );}
           ;

expr_list  : expr_list_ expr {$$ = mknode2("AGRS" , $2 , $1);}
       | {$$ = NULL;}
       ;

expr_list_ : expr_list_ expr COMMA { $$ = mknode2("," , $2 , $1);}
       | {$$ = NULL;}
       ;

id         : IDENT { $$ = mknode2(strdup(yytext) , NULL , NULL);}
           ;

expr       : expr PLUS expr { $$ = mknode2("+" , $1 , $3);}
           | expr MINUS expr { $$ = mknode2("-" , $1 , $3);}
           | expr MULT expr { $$ = mknode2("*" , $1 , $3);}
           | expr DIV expr { $$ = mknode2("/" , $1 , $3);}
           | expr OP_AND expr { $$ = mknode2("&&" , $1 , $3);}
           | expr OP_OR expr { $$ = mknode2("||" , $1 , $3);}
           | expr OP_NE expr { $$ = mknode2("!=" , $1 , $3);}
           | expr OP_EQ expr {$$=mknode2("==",$1,$3);}
           | expr OP_GT expr {$$=mknode2(">",$1,$3);}
           | expr OP_GE expr {$$=mknode2(">=",$1,$3);}
           | expr OP_LT expr {$$=mknode2("<",$1,$3);}
           | expr OP_LE expr {$$=mknode2("<=",$1,$3);}
           | OP_NOT expr {$$=mknode2("!",NULL,$2);}
           | PTR_VAL expr {$$=mknode2("^",NULL,$2);}
           | ADRS expr  {$$=mknode2("&",NULL,$2);}
           | MINUS expr {$$=mknode2("-",NULL,$2);}
           | literal {$$=mknode2($1,NULL,NULL);}
           | fct_call {$$= $1 ;}
           | id {$$= $1;}
           | PAREN_O expr PAREN_C {$$=mknode2("(_)",NULL,$2);}
           | BAR expr BAR {$$=mknode2("|_|",NULL,$2);}
           ;

literal    : CONST_INT {$$ = "const_int";}
           | TRUE_ { $$ = "true" ;}
           | FALSE_ { $$ = "false" ;}
           | CONST_CHAR { $$ = "const_char" ;}
           | CONST_STRING { $$ = "const_string" ;}
           | NULL_ { $$ = "null" ;}
           ;

%%
#include "lex.yy.c"
void main(){
    return yyparse();
}

int tabCount =0;

struct node* mknode2(char* token,node*b1,node*b2)
{

    node* newnode=(node*)malloc(sizeof(node));
    char* newstr;

    if( token ){
        printf("token: %s \n" , token);
        newstr=(char*)malloc(sizeof(token)+1);
        newstr[sizeof(token)]='\0';
        strcpy(newstr,token);
    }
    else{

        newstr=(char*)malloc(3);
        strcpy(newstr,"AA");
    }

    newnode->b1=b1;
    newnode->b2=b2;
    newnode->b3=NULL;
    newnode->b4=NULL;
    newnode->token=newstr;

    return newnode;
}

struct node* mknode3(char* token,node*b1,node*b2,node*b3)
{
    node* newnode= mknode2(token,b1,b2);
    newnode->b3=b3;
    return newnode;
}

struct node* mknode4(char* token,node*b1,node*b2,node*b3,node*b4)
{
    node* newnode= mknode3(token,b1,b2,b3);
    newnode->b4=b4;
    return newnode;
}

void printTabs(){
    int i;
    for(i=0;i<tabCount;i++){
        printf("\t");
    }
}

int printtree(node* tree)
{

    tabCount++;
    printTabs();
    printf("%s\n",tree->token);

    if(tree->b1)printtree(tree->b1);
    if(tree->b2)printtree(tree->b2);
    if(tree->b3)printtree(tree->b3);
    if(tree->b4)printtree(tree->b4);

    tabCount--;
    return 1;
}

int yyerror(){
    printf("ERROR!\n");
    return 0;
}

this is the input file:

void main(int x){
    int y,w,r; int z;
}

this is the output AST in preorder:

FUNC
    void
        main
        int x
            x
        BODY
            DECL
                int z;
                    ;
                DECL
                    int y,w,r;
                        ,
                            ;
                            ,
                                ,
                                ,

the output i expected:

FUNC
    void
        main
        int
            x
        BODY
            DECL
                int
                    z
                DECL
                    int
                        ,
                            y
                            ,
                                w
                                r

As can be seen when I get to the rule: type in my yacc file yytext contains the whole sentence ("int y,w,r;" instead of just "int") and when I get to the rule: id it only contain one token, that happens to be one token forward then the expected token.

- Note that in the function name and the function arguments yytext works properly.

- I tried printing yytext from the lex file and the tokens seems to contain right values.


来源: stackexchange

问:
limit digits in var multiplication total
I have this:

var ivu = (total3);
document.getElementById("project_pay_total_field4").value = "$" +  total3 * 0.07  ;

The multiplication produces this:

$10.080000000000002

--Its too long and when done in regular calculator it only says 10.08; how can i fix that?

Here is the function:

```<code><script type = "text/javascript">

function project_pay_detail() {
var rate = document.getElementById("project_rate_field").value;
var time = document.getElementById("project_time_field").value;
var total1 = (rate * time);
document.getElementById("project_pay_total_field").value = "$" + total1 + ".00";

var rate = document.getElementById("project_rate_field2").value;
var time = document.getElementById("project_time_field2").value;
var total2 = (rate * time);
document.getElementById("project_pay_total_field2").value = "$" + total2 + ".00";

var total3 = (total1 + total2);
document.getElementById("project_pay_total_field3").value = "$" +  total3 + ".00" ;

var ivu = (total3);
document.getElementById("project_pay_total_field4").value = "$" +  total3 * 0.07  ;
}

</script>
</code>```

Heres is the form

```<div id="project_pay">Pay Rate<input type="text" name="project_rate_field" id="project_rate_field" class="field" value="" /></div>

<div id="project_pay">Total Hours<input type="text" name="project_time_field" id="project_time_field" class="field" value="" /></div>

<div id="project_pay">Project Total<input type="text" name="project_pay_total_field" id="project_pay_total_field" class="field" readonly="readonly" value="" /></div>
<input name="project_pay_details_calculate" type="button" value="Calculate1" onClick="project_pay_detail()" /></input>

<br>
<div id="project_pay">Pay Rate2<input type="text" name="project_rate_field2" id="project_rate_field2" class="field" value="" /></div>

<div id="project_pay">Total Hours2<input type="text" name="project_time_field2" id="project_time_field2" class="field" value="" /></div>

<div id="project_pay">Project Total2<input type="text" name="project_pay_total_field2" id="project_pay_total_field2" class="field" title="0.00" readonly="readonly" value="" /></div>

<input name="project_pay_details_refresh" type="button" value="Calculate2" onClick="project_pay_detail()" /></input>

<div id="project_pay">Total<input type="text" name="project_pay_total_field3" id="project_pay_total_field3" class="field" title="0.00" readonly="readonly" value="" /></div>
<div id="project_pay">Ivu<input type="text" name="project_pay_total_field4" id="project_pay_total_field4" class="field" title="0.00" readonly="readonly" value="" /></div>
</div>
</code>```

答:
try using: number.toFixed(x)

```<code>var result = (total3 * 0.07);

document.getElementById("project_pay_total_field4").value = "$" + result.toFixed(2);
</code>```

http://www.w3schools.com/jsref/jsref_tofixed.asp

ContentLicense: CC BY-SA 2.5

Body:
I have this:

var ivu = (total3);
document.getElementById("project_pay_total_field4").value = "$" +  total3 * 0.07  ;

The multiplication produces this:

$10.080000000000002

--Its too long and when done in regular calculator it only says 10.08; how can i fix that?

Here is the function:

Heres is the form

Pay Rate<input type="text" name="project_rate_field" id="project_rate_field" class="field" value="" />

Total Hours<input type="text" name="project_time_field" id="project_time_field" class="field" value="" />

Project Total<input type="text" name="project_pay_total_field" id="project_pay_total_field" class="field" readonly="readonly" value="" />

<input name="project_pay_details_calculate" type="button" value="Calculate1" onClick="project_pay_detail()" /></input>

Pay Rate2<input type="text" name="project_rate_field2" id="project_rate_field2" class="field" value="" />

Total Hours2<input type="text" name="project_time_field2" id="project_time_field2" class="field" value="" />

Project Total2<input type="text" name="project_pay_total_field2" id="project_pay_total_field2" class="field" title="0.00" readonly="readonly" value="" />

<input name="project_pay_details_refresh" type="button" value="Calculate2" onClick="project_pay_detail()" /></input>

Total<input type="text" name="project_pay_total_field3" id="project_pay_total_field3" class="field" title="0.00" readonly="readonly" value="" />

Ivu<input type="text" name="project_pay_total_field4" id="project_pay_total_field4" class="field" title="0.00" readonly="readonly" value="" />

Body:
try using: number.toFixed(x)

var result = (total3 * 0.07);

document.getElementById("project_pay_total_field4").value = "$" + result.toFixed(2);

http://www.w3schools.com/jsref/jsref_tofixed.asp


问:
npm 5 install folder without using symlink
Before publishing my node library, I could use the advice the npm documentation wrote about:

To test a local install, go into some other folder, and then do:

cd ../some-other-folder

npm install ../my-package

Prior to version 5 of npm, I had no problem as it produce what I expected, ie a folder with the output of what I will publish.

However, using npm 5, it now creates a symlink to my local project as described in the npm documentation:

npm install :

Install the package in the directory as a symlink in the current
  project. Its dependencies will be installed before it's linked. If
   sits inside the root of your project, its dependencies may be
  hoisted to the toplevel node_modules as they would for other types of
  dependencies.

How can I use the "old" way to install local project? Or is there a new way to check if my library is correct?

Thank you.

答:
Use npm pack + npm install (as suggested by install-local package)

```<code>npm pack <path-to-local-package>
npm install <package-version.tgz>
</code>```

This will effectively copy your local package to node_modules.
Note that this will package only production relevant files (those listed in the files section of your package.json). So, you can install it in a test app under the package own directory. Something like this:

```<code>my-package
  package.json
  test
    test-app
      package.json
      node_modules
        my-package
</code>```

Assuming that test dir is not included in the files in my-package/package.json.

This works the same way with npm 5 and older versions.

ContentLicense: CC BY-SA 3.0

Body:
Use npm pack + npm install (as suggested by install-local package)

npm pack <path-to-local-package>
npm install <package-version.tgz>

This will effectively copy your local package to node_modules.
Note that this will package only production relevant files (those listed in the files section of your package.json). So, you can install it in a test app under the package own directory. Something like this:

my-package
  package.json
  test
    test-app
      package.json
      node_modules
        my-package

Assuming that test dir is not included in the files in my-package/package.json.

This works the same way with npm 5 and older versions.


问:
Collecting the result of an iteration on one object in to a map with values from another object
This question is an extension to this. I have provided all the needed details here.

If I have 2 collections,

```<code>List<String> domainArr;
List<Person> personArr;
</code>```

I would like to make a minor transformation on each of the elements in the String and then iterate over the personArr to

```<code>List<String> urlArr = strArr.stream()
    .map(str -> "https://" + strArr)
    .collect(Collectors.toList());
</code>```

I have a method like

```<code>List<Person> getPersons(String url){
 /*makes a restful call to the url and gets a List of objects for each URL.*/
}
</code>```

I know from here that I can collect the results into a flattened list like

```<code>strArr.stream()
    .map(str -> getPersons("https://" + str))
    .flatMap(persons -> persons.stream())
    .filter(Objects::nonNull)
    .map(Person::getName)
    .filter(Objects::nonNull)
    .collect(Collectors.toList());
</code>```

I was wondering how get the result in a Map with key as the domainUrl and Value as a list of names obtained by transforming the result of that particular URL?

Say a map like,

```<code>URL1 -> [name1, name2]
URL2 -> [name3, name4]
</code>```

答:
You can use the code below, where resultMap is what you're looking for:

```<code>   domainArr.stream()
            .forEach(domain -> {
                String url = "https://" + domain;
                List<Person> persons = getPersons(url);
                Map<String, List<String>> resultMap = persons.stream()
                        .filter(Objects::nonNull)
                        .map(Person::getName)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toMap(a -> url, Arrays::asList, (a, b) -> {
                            a.addAll(b);
                            return a;
                        }));

            });
</code>```

Body:
This question is an extension to this. I have provided all the needed details here.

If I have 2 collections,

List<String> domainArr;
List<Person> personArr;

I would like to make a minor transformation on each of the elements in the String and then iterate over the personArr to

List<String> urlArr = strArr.stream()
    .map(str -> "https://" + strArr)
    .collect(Collectors.toList());

I have a method like

List<Person> getPersons(String url){
 /*makes a restful call to the url and gets a List of objects for each URL.*/
}

I know from here that I can collect the results into a flattened list like

strArr.stream()
    .map(str -> getPersons("https://" + str))
    .flatMap(persons -> persons.stream())
    .filter(Objects::nonNull)
    .map(Person::getName)
    .filter(Objects::nonNull)
    .collect(Collectors.toList());

I was wondering how get the result in a Map with key as the domainUrl and Value as a list of names obtained by transforming the result of that particular URL?

Say a map like,

URL1 -> [name1, name2]
URL2 -> [name3, name4]

Body:
You can use the code below, where resultMap is what you're looking for:

   domainArr.stream()
            .forEach(domain -> {
                String url = "https://" + domain;
                List<Person> persons = getPersons(url);
                Map<String, List<String>> resultMap = persons.stream()
                        .filter(Objects::nonNull)
                        .map(Person::getName)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toMap(a -> url, Arrays::asList, (a, b) -> {
                            a.addAll(b);
                            return a;
                        }));

            });


问:
How to split a list on an element delimiter
Are there concise and elegant ways of splitting a list in Python into a list of sub-lists by a delimiting element, such that ['a', 'delim', 'b'] -> [['a'], ['b']]?

Here is the example:

```<code>ldat = ['a','b','c','a','b','c','a','b']
dlim = 'c'
lspl = []   # an elegant python one-liner wanted on this line!
print(lspl) # want: [['a', 'b'], ['a', 'b'], ['a', 'b']]
</code>```

Working examples that seem overly complex

I have surveyed documentation and related questions on stackoverflow - many referenced below - which did not answer my question, and am summarizing my research below: several approaches which do generate the desired output, but are verbose and intricate, and what is happening (splitting a list) is not immediately apparent -- you really have to squint.

Are there better ways? I am primarily interested in readability for beginners (e.g. teaching), canonical / 'Pythonic' approaches, and secondarily in the most efficient approaches (e.g. timeit speed). Ideally answers would address both Python 2.7 and 3.x.

with conditional .append()

Loop through the list and either append to the last output list or add a new output list. Based on an example that includes the delimiter, but altered to exclude it. I'm not sure how to make it a one-liner, or if that is even desirable.

```<code>lspl = [[]]
for i in ldat:
    if i==dlim:
        lspl.append([])
    else:
        lspl[-1].append(i)
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]
</code>```

with itertools.groupby

Combine itertools.groupby with list comprehension. Many answers include  delimeters, this is based on those that exclude delimeters.

```<code>import itertools
lspl = [list(y) for x, y in itertools.groupby(ldat, lambda z: z == dlim) if not x]
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]
</code>```

with slicing on indices

Some related questions have discussed how to use slicing after using .index() -- however answers usually focus on finding the first index only. One can extend this approach by first finding a list of indices and then looping through a self-zipped list to slice the ranges.

```<code>indices = [i for i, x in enumerate(ldat) if x == dlim]
lspl = [ldat[s+1:e] for s, e in zip([-1] + indices, indices + [len(ldat)])]
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]
</code>```

However, like all the approaches I have found, this seems like a very complex way of enacting a simple split-on-delimiter operation.

Comparison to string splitting

By comparison and as a model only, here is a working, concise, and elegant way of splitting
a string into a list of sub-strings by a delimiter.

```<code>sdat = 'abcabcab'
dlim = 'c'
sspl = sdat.split(dlim)
print(sspl) # prints: ['ab', 'ab', 'ab']
</code>```

NOTE: I understand there is no split method on lists in Python, and I am not asking about splitting a string. I am also not asking about splitting element-strings into new elements.

答:
or this:</p>

```<code>ldat = ['a','b','c','a','b','c','a','b']
dlim = 'c'
lspl = []   # an elegant python one-liner wanted on this line!
print(lspl) # want: [['a', 'b'], ['a', 'b'], ['a', 'b']]

s = str(ldat).replace(", '%s', " % dlim, "],[")
result = eval(s)
print(result)
</code>```

Body:
Are there concise and elegant ways of splitting a list in Python into a list of sub-lists by a delimiting element, such that ['a', 'delim', 'b'] -> [['a'], ['b']]?

Here is the example:

ldat = ['a','b','c','a','b','c','a','b']
dlim = 'c'
lspl = []   # an elegant python one-liner wanted on this line!
print(lspl) # want: [['a', 'b'], ['a', 'b'], ['a', 'b']]

Working examples that seem overly complex

I have surveyed documentation and related questions on stackoverflow - many referenced below - which did not answer my question, and am summarizing my research below: several approaches which do generate the desired output, but are verbose and intricate, and what is happening (splitting a list) is not immediately apparent -- you really have to squint.

Are there better ways? I am primarily interested in readability for beginners (e.g. teaching), canonical / 'Pythonic' approaches, and secondarily in the most efficient approaches (e.g. timeit speed). Ideally answers would address both Python 2.7 and 3.x.

with conditional .append()

Loop through the list and either append to the last output list or add a new output list. Based on an example that includes the delimiter, but altered to exclude it. I'm not sure how to make it a one-liner, or if that is even desirable.

lspl = [[]]
for i in ldat:
    if i==dlim:
        lspl.append([])
    else:
        lspl[-1].append(i)
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]

with itertools.groupby

Combine itertools.groupby with list comprehension. Many answers include  delimeters, this is based on those that exclude delimeters.

import itertools
lspl = [list(y) for x, y in itertools.groupby(ldat, lambda z: z == dlim) if not x]
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]

with slicing on indices

Some related questions have discussed how to use slicing after using .index() -- however answers usually focus on finding the first index only. One can extend this approach by first finding a list of indices and then looping through a self-zipped list to slice the ranges.

indices = [i for i, x in enumerate(ldat) if x == dlim]
lspl = [ldat[s+1:e] for s, e in zip([-1] + indices, indices + [len(ldat)])]
print(lspl) # prints: [['a', 'b'], ['a', 'b'], ['a', 'b']]

However, like all the approaches I have found, this seems like a very complex way of enacting a simple split-on-delimiter operation.

Comparison to string splitting

By comparison and as a model only, here is a working, concise, and elegant way of splitting
a string into a list of sub-strings by a delimiter.

sdat = 'abcabcab'
dlim = 'c'
sspl = sdat.split(dlim)
print(sspl) # prints: ['ab', 'ab', 'ab']

NOTE: I understand there is no split method on lists in Python, and I am not asking about splitting a string. I am also not asking about splitting element-strings into new elements.

Body:
or this:

ldat = ['a','b','c','a','b','c','a','b']
dlim = 'c'
lspl = []   # an elegant python one-liner wanted on this line!
print(lspl) # want: [['a', 'b'], ['a', 'b'], ['a', 'b']]

s = str(ldat).replace(", '%s', " % dlim, "],[")
result = eval(s)
print(result)


问:
Mesh grid using triangle strips rendering incorrectly?
I am having trouble rendering a mesh grid using VAOs and triangle strips in OpenGL.

Here is my code to generate the vertices and indices and put them in their respective buffers.

```<code>void HeightField::generateMesh(int tesselation) {
// generate a mesh in range -1 to 1 in x and z
int verticesPerRow = sqrt(tesselation / 2) + 1;
float* verts = NULL;
verts = new float[verticesPerRow*verticesPerRow*3];

//Generate Vertices
float z = 1;
int idx = 0;
for(int j = 0; j < verticesPerRow; j++) {
    float x = -1;
    for (int k = 0; k < verticesPerRow; k++) {
        verts[idx++] = x;
        verts[idx++] = 0;
        verts[idx++] = z;
        x += (2.0f/float(verticesPerRow-1));
    }
    z -= (2.0f / float(verticesPerRow-1));
}

printf("\n VERTICES \n");
for (int o = 0; o < verticesPerRow*verticesPerRow*3; o++) {
    printf("%f, ", verts[o]);
    if (o % 3 == 2) {
        printf("\n");
    }
}

//Generate indices

int rows = sqrt(tesselation / 2);
int columns = rows+1;
int* indices = NULL;
int indicesAmount = 2 * rows*columns +  rows;
indices = new int[indicesAmount];
idx = 0;
for (int r = 0; r < rows; r++) {
    for (int c = 0; c < columns; c++) {

        indices[idx++] = (r + 1) * columns + c;
        indices[idx++] = r * columns + c;
        //printf("%i, %i,  ", indices[idx - 2], indices[idx - 1]);
        if (r == rows - 1) {
            indices[idx] = (r + 1) * columns + c - 1;
        }
    }

    if (r < rows - 1) {
        indices[idx++] = 9999;
        //printf(", %i, ", indices[-1]);
    }
}

for (int o = 0; o < indicesAmount; o++) {
    printf("%i, ", indices[o]);
    if (o % 3 == 2) {
        printf("\n");
    }
}

m_numIndices = indicesAmount;

printf("Vertices Per Row: %i \n", verticesPerRow);
printf("Number of indices: %i \n", m_numIndices);

glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);

glGenBuffers(1, &m_positionBuffer);                                                 // Create a handle for the vertex position buffer
glBindBuffer(GL_ARRAY_BUFFER, m_positionBuffer);                                    // Set the newly created buffer as the current one
glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 3, verts, GL_STATIC_DRAW);        // Send the vetex position data to the current buffer
glVertexAttribPointer(0, 3, GL_FLOAT, false/*normalized*/, 0/*stride*/, 0/*offset*/);
glEnableVertexAttribArray(0);

glGenBuffers(1, &m_uvBuffer);                                                   // Create a handle for the vertex position buffer
glBindBuffer(GL_ARRAY_BUFFER, m_uvBuffer);                                  // Set the newly created buffer as the current one
glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 2, texCoords, GL_STATIC_DRAW);        // Send the vetex position data to the current buffer
//glVertexAttribPointer(2, 2, GL_FLOAT, false/*normalized*/, 0/*stride*/, 0/*offset*/);
//glEnableVertexAttribArray(2);

glGenBuffers(1, &m_indexBuffer);                                                    // Create a handle for the vertex position buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);                                   // Set the newly created buffer as the current one
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_numIndices, indices, GL_STATIC_DRAW);       // Send the vetex position data to the current buffer}
</code>```

Here is my code to render it:

```<code>void HeightField::submitTriangles(void){
if (m_vao == UINT32_MAX) {
    std::cout << "No vertex array is generated, cannot draw anything.\n";
    return;
}

glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(9999);
glBindVertexArray(m_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLE_STRIP, m_numIndices, GL_UNSIGNED_INT, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glDisable(GL_PRIMITIVE_RESTART); }
</code>```

Here is a screen shot of what it looks like trying to render a 16x16 grid.

If I increase the number of rows and columns I try to render, I get more rows and columns looking the way I want them to, but the "contour" of the entire figure looks the same, having the diamond like shape you see in the picture.

答:
The problem was with

```<code>glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 3, verts, GL_STATIC_DRAW);
</code>```

Appearently it expects the size in bytes, and not the length of the array (silly me).

Changing the above line to

```<code>glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 3 * sizeof(float), verts, GL_STATIC_DRAW);
</code>```

and likewise for all other buffers fixed the problem.

Body:
I am having trouble rendering a mesh grid using VAOs and triangle strips in OpenGL.

Here is my code to generate the vertices and indices and put them in their respective buffers.

void HeightField::generateMesh(int tesselation) {
// generate a mesh in range -1 to 1 in x and z
int verticesPerRow = sqrt(tesselation / 2) + 1;
float* verts = NULL;
verts = new float[verticesPerRow*verticesPerRow*3];

//Generate Vertices
float z = 1;
int idx = 0;
for(int j = 0; j < verticesPerRow; j++) {
    float x = -1;
    for (int k = 0; k < verticesPerRow; k++) {
        verts[idx++] = x;
        verts[idx++] = 0;
        verts[idx++] = z;
        x += (2.0f/float(verticesPerRow-1));
    }
    z -= (2.0f / float(verticesPerRow-1));
}

printf("\n VERTICES \n");
for (int o = 0; o < verticesPerRow*verticesPerRow*3; o++) {
    printf("%f, ", verts[o]);
    if (o % 3 == 2) {
        printf("\n");
    }
}

//Generate indices

int rows = sqrt(tesselation / 2);
int columns = rows+1;
int* indices = NULL;
int indicesAmount = 2 * rows*columns +  rows;
indices = new int[indicesAmount];
idx = 0;
for (int r = 0; r < rows; r++) {
    for (int c = 0; c < columns; c++) {

        indices[idx++] = (r + 1) * columns + c;
        indices[idx++] = r * columns + c;
        //printf("%i, %i,  ", indices[idx - 2], indices[idx - 1]);
        if (r == rows - 1) {
            indices[idx] = (r + 1) * columns + c - 1;
        }
    }

    if (r < rows - 1) {
        indices[idx++] = 9999;
        //printf(", %i, ", indices[-1]);
    }
}

for (int o = 0; o < indicesAmount; o++) {
    printf("%i, ", indices[o]);
    if (o % 3 == 2) {
        printf("\n");
    }
}

m_numIndices = indicesAmount;

printf("Vertices Per Row: %i \n", verticesPerRow);
printf("Number of indices: %i \n", m_numIndices);

glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);

glGenBuffers(1, &m_positionBuffer);                                                 // Create a handle for the vertex position buffer
glBindBuffer(GL_ARRAY_BUFFER, m_positionBuffer);                                    // Set the newly created buffer as the current one
glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 3, verts, GL_STATIC_DRAW);        // Send the vetex position data to the current buffer
glVertexAttribPointer(0, 3, GL_FLOAT, false/*normalized*/, 0/*stride*/, 0/*offset*/);
glEnableVertexAttribArray(0);

glGenBuffers(1, &m_uvBuffer);                                                   // Create a handle for the vertex position buffer
glBindBuffer(GL_ARRAY_BUFFER, m_uvBuffer);                                  // Set the newly created buffer as the current one
glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 2, texCoords, GL_STATIC_DRAW);        // Send the vetex position data to the current buffer
//glVertexAttribPointer(2, 2, GL_FLOAT, false/*normalized*/, 0/*stride*/, 0/*offset*/);
//glEnableVertexAttribArray(2);

glGenBuffers(1, &m_indexBuffer);                                                    // Create a handle for the vertex position buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);                                   // Set the newly created buffer as the current one
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_numIndices, indices, GL_STATIC_DRAW);       // Send the vetex position data to the current buffer}

Here is my code to render it:

void HeightField::submitTriangles(void){
if (m_vao == UINT32_MAX) {
    std::cout << "No vertex array is generated, cannot draw anything.\n";
    return;
}

glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(9999);
glBindVertexArray(m_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLE_STRIP, m_numIndices, GL_UNSIGNED_INT, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glDisable(GL_PRIMITIVE_RESTART); }

Here is a screen shot of what it looks like trying to render a 16x16 grid.

If I increase the number of rows and columns I try to render, I get more rows and columns looking the way I want them to, but the "contour" of the entire figure looks the same, having the diamond like shape you see in the picture.

Body:
The problem was with

glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 3, verts, GL_STATIC_DRAW);

Appearently it expects the size in bytes, and not the length of the array (silly me).

Changing the above line to

glBufferData(GL_ARRAY_BUFFER, verticesPerRow*verticesPerRow * 3 * sizeof(float), verts, GL_STATIC_DRAW);

and likewise for all other buffers fixed the problem.

ContentLicense: CC BY-SA 4.0


问:
How should I avoid 404 errors when scraping with R
I'm accessing web pages by looping over a couple of variables to insert into the URL

There will be occasional 404 errors.

How do I insert some sort of catch for these pages to avoid breaking the code. I currently use the XML package but of course could load others if appropriate

TIA

答:
Most of times I use RCurl::url.exists(). In case you have a list or a data frame containing all the urls you can try this:

```<code>map(p, ~ifelse(RCurl::url.exists(.), ., NA))
</code>```

HTH!

Body:
Most of times I use RCurl::url.exists(). In case you have a list or a data frame containing all the urls you can try this:

map(p, ~ifelse(RCurl::url.exists(.), ., NA))

HTH!


问:
NSLinguisticTagger enumerateTagsInRange doesn't work on device with NSLinguisticTagSchemeNameTypeOrLexicalClass
Here's the code I'm using, it prints nothing no matter what sentence I use on the device. On simulator it works fine!

```<code>- (NSMutableArray *)getTagEntries:(NSString *)sentence {
  NSArray<NSLinguisticTagScheme> *tagSchemes = [NSLinguisticTagger availableTagSchemesForLanguage:@"en"];
  NSLinguisticTaggerOptions options = NSLinguisticTaggerJoinNames | NSLinguisticTaggerOmitWhitespace;
  NSLinguisticTagger *linguisticTagger = [[NSLinguisticTagger alloc] initWithTagSchemes:tagSchemes options:options];

  linguisticTagger.string = sentence;

  __block NSMutableArray *tagEntries = [@[] mutableCopy];
  [linguisticTagger enumerateTagsInRange:NSMakeRange(0, sentence.length) scheme:NSLinguisticTagSchemeNameTypeOrLexicalClass options:options usingBlock:^(NSLinguisticTag tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
    NSString *token = [sentence substringWithRange:tokenRange];
    NSLog(@"%@ -> %@", token, tag);
    [tagEntries addObject:@{@"token":token, @"tag":tag}];
  }];
  return tagEntries;
}
</code>```

When I try to print out the available schemes on my iPhone, Lexical is not an option. How come!?

```<code>NSArray<NSLinguisticTagScheme> *availSchemes = [NSLinguisticTagger availableTagSchemesForLanguage:@"en"];
for (NSLinguisticTagScheme scheme in availSchemes) {
  NSLog(@"Tag scheme %@", scheme);
}
// output:
// Tag scheme Language
// Tag scheme Script
// Tag scheme TokenType
</code>```

Using iPhone 6+ with iOS 11.

答: Unfortunately, the answer was changing devices. My iPhone X does not have this issue. It may be due to having a dedicated ML chip that the 6s and newer phones have.</p>

Body:
Here's the code I'm using, it prints nothing no matter what sentence I use on the device. On simulator it works fine!

- (NSMutableArray *)getTagEntries:(NSString *)sentence {
  NSArray<NSLinguisticTagScheme> *tagSchemes = [NSLinguisticTagger availableTagSchemesForLanguage:@"en"];
  NSLinguisticTaggerOptions options = NSLinguisticTaggerJoinNames | NSLinguisticTaggerOmitWhitespace;
  NSLinguisticTagger *linguisticTagger = [[NSLinguisticTagger alloc] initWithTagSchemes:tagSchemes options:options];

  linguisticTagger.string = sentence;

  __block NSMutableArray *tagEntries = [@[] mutableCopy];
  [linguisticTagger enumerateTagsInRange:NSMakeRange(0, sentence.length) scheme:NSLinguisticTagSchemeNameTypeOrLexicalClass options:options usingBlock:^(NSLinguisticTag tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
    NSString *token = [sentence substringWithRange:tokenRange];
    NSLog(@"%@ -> %@", token, tag);
    [tagEntries addObject:@{@"token":token, @"tag":tag}];
  }];
  return tagEntries;
}

When I try to print out the available schemes on my iPhone, Lexical is not an option. How come!?

NSArray<NSLinguisticTagScheme> *availSchemes = [NSLinguisticTagger availableTagSchemesForLanguage:@"en"];
for (NSLinguisticTagScheme scheme in availSchemes) {
  NSLog(@"Tag scheme %@", scheme);
}
// output:
// Tag scheme Language
// Tag scheme Script
// Tag scheme TokenType

Using iPhone 6+ with iOS 11.


问:
How to only pass non-empty variables as function parameters?
I have a function that will always receive 3 arguments; at least one arg will have a value, but one or more may not. After working with the arguments in this function, I need to send only the arguments with values to another function. Furthermore, the second function needs at least 2 args, so I only want to execute it if at least 2 of my args have a value. What is the best way to accomplish this?

Here is an example of my code structure:

```<code>function doSomething(arg1, arg2, arg3) {
    // Do something with args

    // Only want to send args with values to this function (min 2 args)
    return doSomethingElse(arg1, arg2, arg3);

}
</code>```

Edit: The second function, doSomethingElse(), can receive any number of args with a minimum of 2.

答:
You can use apply() with an array so you can pass what you want.

```<code>function doSomething() {

  // convert the arguments to an array
  var args = Array.from(arguments);
  // var args = [...arguments]; // or use spread operator

  // filter the array with only thing that are not undefined (change your check)
  var  argsWithValues = args.filter(function (item) { return item !== undefined })
  // const argsWithValues = args.filter(item = > item !== undefined)

  // call function if there are 2 items or more
  return argsWithValues.length > 1 ? doSomethingElse.apply(this, argsWithValues) : null;

}
</code>```

Body:
I have a function that will always receive 3 arguments; at least one arg will have a value, but one or more may not. After working with the arguments in this function, I need to send only the arguments with values to another function. Furthermore, the second function needs at least 2 args, so I only want to execute it if at least 2 of my args have a value. What is the best way to accomplish this?

Here is an example of my code structure:

function doSomething(arg1, arg2, arg3) {
    // Do something with args

    // Only want to send args with values to this function (min 2 args)
    return doSomethingElse(arg1, arg2, arg3);

}

Edit: The second function, doSomethingElse(), can receive any number of args with a minimum of 2.

Body:
You can use apply() with an array so you can pass what you want.

function doSomething() {

  // convert the arguments to an array
  var args = Array.from(arguments);
  // var args = [...arguments]; // or use spread operator

  // filter the array with only thing that are not undefined (change your check)
  var  argsWithValues = args.filter(function (item) { return item !== undefined })
  // const argsWithValues = args.filter(item = > item !== undefined)

  // call function if there are 2 items or more
  return argsWithValues.length > 1 ? doSomethingElse.apply(this, argsWithValues) : null;

}


问:
exec() fails randomly with strange behaviour
I'm trying to use exec() to do a batch PDF to JPEG conversation using pdftoppm utility on an Ubuntu-based server.
The main part of PHP script converter.php is:

```<code>for ($i = 1; $i <= $PDF_pageCount; $i++){
    exec("pdftoppm -jpeg -f $i -l $i '$PDF_source' '$PNG_output' 2>&1", $Output, $Status);
    sleep(1); //  To simulate delay and let the other instance to run while this one is inside the loop.
}
</code>```

Now, take two files for example:

./A/source_file.pdf

./B/source_file.pdf

These files are exist on their place on the disk.
The parent folders' (A/ & B/) owner and permissions are:

UID: www-data, GID: www-data, Permission: 755

The files' (both source_file.pdf) owner and permissions are:

UID: www-data, GID: www-data, Permission: 644

There code works file when only one instance of script is being run and generates the outputs without any problem. For example, with $PDF_source = './A/source_file.pdf'. All pages will convert to JPEG files successfully.

But when the second instance of script runs, exec() function works on only one of them and in other one, it produces the following error with exit status 1:

```<code>I/O Error: Couldn't open file '/path/to/source_file.pdf': No such file or directory.
</code>```

In other word, one of files will be converted to JPEG and the other one (although the first one might be ended already) will produce the error on output.
Note that all of the paths to files are correct and files exist.

Also note that the script is being run from CLI with the following command in a cronjob (but might be executed from a standard web request too):

```<code>/path/to/php -q /path/to/converter.php
</code>```

I tried to prevent running more than one instance of file in a time with the following code in the beginning of the script:

```<code>class Lock{
    private $fp;
    function __construct(){
        $this->fp=fopen(__FILE__,'r');
        if (!flock($this->fp,LOCK_EX|LOCK_NB)) {
            die('ARN'.PHP_EOL);
        }
    }
    function __destruct(){
        flock($this->fp,LOCK_UN);
        fclose($this->fp);
    }
}

$lock=new Lock();
</code>```

What is the problem exactly? How can I solve the problem?

答:
Well, I just added __DIR__.'/'. before inputs and it's working now.

But I still want to find out why it was working before adding the directory in the first execution of script?

Body:
I'm trying to use exec() to do a batch PDF to JPEG conversation using pdftoppm utility on an Ubuntu-based server.
The main part of PHP script converter.php is:

for ($i = 1; $i <= $PDF_pageCount; $i++){
    exec("pdftoppm -jpeg -f $i -l $i '$PDF_source' '$PNG_output' 2>&1", $Output, $Status);
    sleep(1); //  To simulate delay and let the other instance to run while this one is inside the loop.
}

Now, take two files for example:

./A/source_file.pdf

./B/source_file.pdf

These files are exist on their place on the disk.
The parent folders' (A/ & B/) owner and permissions are:

UID: www-data, GID: www-data, Permission: 755

The files' (both source_file.pdf) owner and permissions are:

UID: www-data, GID: www-data, Permission: 644

There code works file when only one instance of script is being run and generates the outputs without any problem. For example, with $PDF_source = './A/source_file.pdf'. All pages will convert to JPEG files successfully.

But when the second instance of script runs, exec() function works on only one of them and in other one, it produces the following error with exit status 1:

I/O Error: Couldn't open file '/path/to/source_file.pdf': No such file or directory.

In other word, one of files will be converted to JPEG and the other one (although the first one might be ended already) will produce the error on output.
Note that all of the paths to files are correct and files exist.

Also note that the script is being run from CLI with the following command in a cronjob (but might be executed from a standard web request too):

/path/to/php -q /path/to/converter.php

I tried to prevent running more than one instance of file in a time with the following code in the beginning of the script:

class Lock{
    private $fp;
    function __construct(){
        $this->fp=fopen(__FILE__,'r');
        if (!flock($this->fp,LOCK_EX|LOCK_NB)) {
            die('ARN'.PHP_EOL);
        }
    }
    function __destruct(){
        flock($this->fp,LOCK_UN);
        fclose($this->fp);
    }
}

$lock=new Lock();

What is the problem exactly? How can I solve the problem?


问:
merge update oracle unable to get a stable set of rows
I am trying to update a table in Oracle based on another table (inner join) but the matching fields match on more than 1 row so I get an error:

unable to get a stable set of rows

```<code>    MERGE INTO C
    USING D
    ON (C.SYSTEM = D.SYSTEM)
    WHEN MATCHED THEN
    UPDATE SET C.REF_CD = D.CODE,
               C.REF_DT = TO_DATE('12/05/2017', 'MM/DD/YYYY')
       WHERE C.CODE = '123'
       AND D.CODE IS NOT NULL
       AND C.CLOSED = 'N'
       AND C.RCVD_DT >= TO_DATE('12/01/2017', 'MM/DD/YYYY')
       AND C.RCVD_DT <= TO_DATE('12/04/2017', 'MM/DD/YYYY')
       AND SUBSTR(C.SSN,7,3) >= D.FROM
       AND SUBSTR(C.SSN,7,3) <= D.TO;
</code>```

As a SELECT statement, I can pull this information using an inner join. But as a merge statement, I get the above error. SYSTEM is the only matching data in both tables.  How can I rewrite the above in a way that it will not error out?

答:
I am going to show what the source of this error is.

Consider the below simple example:

```<code>CREATE TABLE A_100(
  x_system int,
  val int
);

INSERT INTO a_100 values( 1, 100 );
INSERT INTO a_100 values( 2, 200 );

CREATE TABLE B_100(
  x_system int,
  val int
);

INSERT INTO b_100 values( 1, 1100 );
INSERT INTO b_100 values( 2, 2000 );
INSERT INTO b_100 values( 2, 3000 );

commit;
</code>```

Now please consider this join:

```<code>SELECT *
FROM A_100 a
JOIN B_100 b
ON a.x_system = b.x_system AND a.x_system = 1
;

| X_SYSTEM | VAL | X_SYSTEM |  VAL |
|----------|-----|----------|------|
|        1 | 100 |        1 | 1100 |
</code>```

the above query gives one unique record from the table B_100. If you use this join condition in a merge statement, the merge will run without any error:

```<code>MERGE INTO A_100 a
USING B_100 b
ON ( a.x_system = b.x_system AND a.x_system = 1)
WHEN MATCHED THEN UPDATE SET a.val = b.val
;

1 row merged.
</code>```

Now please consider the below join:

```<code>SELECT *
FROM A_100 a
JOIN B_100 b
ON a.x_system = b.x_system AND a.x_system = 2
;

| X_SYSTEM | VAL | X_SYSTEM |  VAL |
|----------|-----|----------|------|
|        2 | 200 |        2 | 2000 |
|        2 | 200 |        2 | 3000 |
</code>```

The above join, for one record from A_100 gives two records from B_100.

If you try to use MERGE with the above join condition you will get the following:

```<code>MERGE INTO A_100 a
USING B_100 b
ON ( a.x_system = b.x_system AND a.x_system = 2)
WHEN MATCHED THEN UPDATE SET a.val = b.val
;

Error report -
ORA-30926: unable to get a stable set of rows in the source tables
</code>```

Oracle simply says you :

The query for one record from the left table returned two values:
  2000 and 3000 from the right table.

  I can not assign two values from the right table to a single scalar field of the left table, this is impossible.

  Please change the join condition so that it gives only one unique
  record from the right table for each record in the left table

Body:
I am trying to update a table in Oracle based on another table (inner join) but the matching fields match on more than 1 row so I get an error:

unable to get a stable set of rows

    MERGE INTO C
    USING D
    ON (C.SYSTEM = D.SYSTEM)
    WHEN MATCHED THEN
    UPDATE SET C.REF_CD = D.CODE,
               C.REF_DT = TO_DATE('12/05/2017', 'MM/DD/YYYY')
       WHERE C.CODE = '123'
       AND D.CODE IS NOT NULL
       AND C.CLOSED = 'N'
       AND C.RCVD_DT >= TO_DATE('12/01/2017', 'MM/DD/YYYY')
       AND C.RCVD_DT <= TO_DATE('12/04/2017', 'MM/DD/YYYY')
       AND SUBSTR(C.SSN,7,3) >= D.FROM
       AND SUBSTR(C.SSN,7,3) <= D.TO;

As a SELECT statement, I can pull this information using an inner join. But as a merge statement, I get the above error. SYSTEM is the only matching data in both tables.  How can I rewrite the above in a way that it will not error out?

Body:
I am going to show what the source of this error is.

Consider the below simple example:

CREATE TABLE A_100(
  x_system int,
  val int
);

INSERT INTO a_100 values( 1, 100 );
INSERT INTO a_100 values( 2, 200 );

CREATE TABLE B_100(
  x_system int,
  val int
);

INSERT INTO b_100 values( 1, 1100 );
INSERT INTO b_100 values( 2, 2000 );
INSERT INTO b_100 values( 2, 3000 );

commit;

Now please consider this join:

SELECT *
FROM A_100 a
JOIN B_100 b
ON a.x_system = b.x_system AND a.x_system = 1
;

| X_SYSTEM | VAL | X_SYSTEM |  VAL |
|----------|-----|----------|------|
|        1 | 100 |        1 | 1100 |

the above query gives one unique record from the table B_100. If you use this join condition in a merge statement, the merge will run without any error:

MERGE INTO A_100 a
USING B_100 b
ON ( a.x_system = b.x_system AND a.x_system = 1)
WHEN MATCHED THEN UPDATE SET a.val = b.val
;

1 row merged.

Now please consider the below join:

SELECT *
FROM A_100 a
JOIN B_100 b
ON a.x_system = b.x_system AND a.x_system = 2
;

| X_SYSTEM | VAL | X_SYSTEM |  VAL |
|----------|-----|----------|------|
|        2 | 200 |        2 | 2000 |
|        2 | 200 |        2 | 3000 |

The above join, for one record from A_100 gives two records from B_100.

If you try to use MERGE with the above join condition you will get the following:

MERGE INTO A_100 a
USING B_100 b
ON ( a.x_system = b.x_system AND a.x_system = 2)
WHEN MATCHED THEN UPDATE SET a.val = b.val
;

Error report -
ORA-30926: unable to get a stable set of rows in the source tables

Oracle simply says you :

The query for one record from the left table returned two values:
  2000 and 3000 from the right table.

  I can not assign two values from the right table to a single scalar field of the left table, this is impossible.

  Please change the join condition so that it gives only one unique
  record from the right table for each record in the left table


问:
Return Function not Working When trying to convert Integer into String
```<code>import UIKit

var str = "Hello, playground"
let NumberofStopLights: Int = 4
var population: Int
population = 5000
let TownName = "HappyPlace"
let TownDescription = return "/(TownName) has a population of /(population) and /(numberofStopLights) Stop Lights
print (TownDescription)
</code>```

I want to have the integers automatically go into the /(TownName), /(population) and /(numberStopLights) spaces, tried using the return function but it did not work. SO..... I tried doing this based off another post on Stack Overflow, which said to put return right in front of it but that did not work, so... what next? (Code above)

答:
You don't need the return, also your interpolation is wrong. Should be \() instead of /() and you forgot the last " when declaring your Townname string.

```<code>var str = "Hello, playground"
let NumberofStopLights: Int = 4
var population: Int
population = 5000
let TownName = "HappyPlace"
let TownDescription = "\(TownName) has a population of \(population) and \(NumberofStopLights) Stop Lights"
print (TownDescription)
</code>```

You should also try to use upper and lowercase the correct way, although the compiler doesn't care, but it will make your life a lot easier in the end!

Body:
import UIKit

var str = "Hello, playground"
let NumberofStopLights: Int = 4
var population: Int
population = 5000
let TownName = "HappyPlace"
let TownDescription = return "/(TownName) has a population of /(population) and /(numberofStopLights) Stop Lights
print (TownDescription)

I want to have the integers automatically go into the /(TownName), /(population) and /(numberStopLights) spaces, tried using the return function but it did not work. SO..... I tried doing this based off another post on Stack Overflow, which said to put return right in front of it but that did not work, so... what next? (Code above)

Body:
You don't need the return, also your interpolation is wrong. Should be \() instead of /() and you forgot the last " when declaring your Townname string.

var str = "Hello, playground"
let NumberofStopLights: Int = 4
var population: Int
population = 5000
let TownName = "HappyPlace"
let TownDescription = "\(TownName) has a population of \(population) and \(NumberofStopLights) Stop Lights"
print (TownDescription)

You should also try to use upper and lowercase the correct way, although the compiler doesn't care, but it will make your life a lot easier in the end!


问:
Convert number to date in Ruby
I get a number representing date from a back-end, and I'm trying to convert it to a date this way:

```<code>number = item["created"].to_i
number #=> 1512387277084
DateTime.strptime(number.to_s ,'%s') #=> 49895-08-24T08:58:04+00:00
Time.at(number).utc #=> 49895-08-24 08:58:04 UTC
Time.at(number) #=> 49895-08-24 11:58:04 +0300
</code>```

But this is a wrong result.

If I use Epoch & Unix Timestamp Conversion Tools, I get this result:

```<code>1512387277084
Assuming that this timestamp is in milliseconds:
GMT: Monday, December 4, 2017 11:34:37.084 AM
Your time zone: Monday, December 4, 2017 2:34:37.084 PM GMT+03:00
</code>```

Time.at(number) doesn't work.

How to convert it correctly?

答:
According to the ruby documentation takes the at method, of the Time class, as argument "the number of seconds" since the Epoch not the "milliseconds" since the Epoch.
Another variant takes as arguments the "seconds" since the Epoch and "Microseconds with frac".

You need to convert number (the input) from ms to sec and us to get the expected / correct result.

Examples

Wrong (ms interpeted as seconds):

```<code>> number = 1512387277084 # ms since epoch
=> 1512387277084
> Time.at(number)
=> 49895-08-24 10:58:04 +0200
</code>```

Seconds with fractal:

```<code>> number2 = number / 1000.0
=> 1512387277.084
> Time.at(number2)
=> 2017-12-04 12:34:37 +0100
> Time.at(number2).usec
=> 84000
> Time.at(number2).nsec
=> 84000110 # Wrong of by 110 ns

> Time.at(number2.round(3)).nsec
=> 84000110 # Wrong of by 110 ns
> Time.at(number2.round(2)).usec
=> 79999 # Wrong
> Time.at(number2.round(2)).nsec
=> 79999923 # Wrong
</code>```

Seconds only:

```<code>> number3 = number / 1000
=> 1512387277
> Time.at(number3)
=> 2017-12-04 12:34:37 +0100
> Time.at(number3).usec
=> 0 # Wrong
> Time.at(number3).nsec
=> 0 # Wrong
</code>```

Seconds and Microseconds:

```<code>ms = number % 1000 # Milliseconds
=> 84
> us = ms * 1000 # Microseconds
=> 84000
> Time.at(number3, us)
=> 2017-12-04 12:34:37 +0100
> Time.at(number3, us).usec
=> 84000 # OK
> Time.at(number3, us).nsec
=> 84000000 # OK
> Time.at(number3, us).to_f
=> 1512387277.084 # OK
</code>```

Update 2

Seconds as Rational

```<code>> number4 = number.quo(1000)
=> (378096819271/250)
> Time.at(number4)
=> 2017-12-04 12:34:37 +0100
> Time.at(number4).usec
=> 84000 # OK
> Time.at(number4).nsec
=> 84000000 # OK
> Time.at(number4).to_f
=> 1512387277.084 # OK
</code>```

Title: Convert number to date in Ruby

Body:
I get a number representing date from a back-end, and I'm trying to convert it to a date this way:

number = item["created"].to_i
number #=> 1512387277084
DateTime.strptime(number.to_s ,'%s') #=> 49895-08-24T08:58:04+00:00
Time.at(number).utc #=> 49895-08-24 08:58:04 UTC
Time.at(number) #=> 49895-08-24 11:58:04 +0300

But this is a wrong result.

If I use Epoch & Unix Timestamp Conversion Tools, I get this result:

1512387277084
Assuming that this timestamp is in milliseconds:
GMT: Monday, December 4, 2017 11:34:37.084 AM
Your time zone: Monday, December 4, 2017 2:34:37.084 PM GMT+03:00

Time.at(number) doesn't work.

How to convert it correctly?

Body:
According to the ruby documentation takes the at method, of the Time class, as argument "the number of seconds" since the Epoch not the "milliseconds" since the Epoch.
Another variant takes as arguments the "seconds" since the Epoch and "Microseconds with frac".

You need to convert number (the input) from ms to sec and us to get the expected / correct result.

Examples

Wrong (ms interpeted as seconds):

> number = 1512387277084 # ms since epoch
=> 1512387277084
> Time.at(number)
=> 49895-08-24 10:58:04 +0200

Seconds with fractal:

> number2 = number / 1000.0
=> 1512387277.084
> Time.at(number2)
=> 2017-12-04 12:34:37 +0100
> Time.at(number2).usec
=> 84000
> Time.at(number2).nsec
=> 84000110 # Wrong of by 110 ns

> Time.at(number2.round(3)).nsec
=> 84000110 # Wrong of by 110 ns
> Time.at(number2.round(2)).usec
=> 79999 # Wrong
> Time.at(number2.round(2)).nsec
=> 79999923 # Wrong

Seconds only:

> number3 = number / 1000
=> 1512387277
> Time.at(number3)
=> 2017-12-04 12:34:37 +0100
> Time.at(number3).usec
=> 0 # Wrong
> Time.at(number3).nsec
=> 0 # Wrong

Seconds and Microseconds:

ms = number % 1000 # Milliseconds
=> 84
> us = ms * 1000 # Microseconds
=> 84000
> Time.at(number3, us)
=> 2017-12-04 12:34:37 +0100
> Time.at(number3, us).usec
=> 84000 # OK
> Time.at(number3, us).nsec
=> 84000000 # OK
> Time.at(number3, us).to_f
=> 1512387277.084 # OK

Update 2

Seconds as Rational

> number4 = number.quo(1000)
=> (378096819271/250)
> Time.at(number4)
=> 2017-12-04 12:34:37 +0100
> Time.at(number4).usec
=> 84000 # OK
> Time.at(number4).nsec
=> 84000000 # OK
> Time.at(number4).to_f
=> 1512387277.084 # OK


问:
Ionic Date object locked to GMT on Android 7.1.1 (API 25)
I'm making a cross-platform app using Ionic, and one of the things I have to do is schedule some notifications. On iOS this process works perfectly, but for some reason in the Android simulator it insists on using GMT+0000 as the timezone, even though that is not correct. (Namely, new Date() turns into DD MM dd yyyy hh:mm:ss GMT+0000 (GMT), when it should be using my local timezone.)

Any help would be greatly appreciated.

EDIT: I should mention, the time zone is correctly set on the simulator (both the status bar clock and the settings app confirm this).

EDIT 2: It only happens on Android 7.1.1 (API 25). API 24 and 26 both work correctly, but for some unknown reason 25 refuses to give the timezone.

答: Turns out I was simply using outdated plugins. I updated everything and the problem went away.</p>


问:
How to get websites source code in to webpage as result using PHP
I want to get some website source code into webpage as result using php.

Here is my html code.i want to add php code to checkout website source code as result.

```<code><html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <center>
        <form method="post">
            <h1>Website source code</h1>
            <input type="text" name="url" placeholder="Website Url"><input type="submit" value=">>">
        </form>
    </center>
</body>
</html>
</code>```

Here is my php code to export html source code.

```<code>[[-- <?php $all_lines = file('example.com/');
foreach ($all_lines as $line_num => $line) {
    echo "Code.-{$line_num}: " . htmlspecialchars($line) . "\n";
} ?> --]] –
</code>```

答:
If you want to get the HTML source code of an URL, you can use cURL :

```<code><?php
$ch = curl_init("http://www.example.com");
$html= curl_exec($ch);
curl_close($ch);
echo htmlspecialchars($html);
?>
</code>```

more info here cUrl - getting the html response body and here php: Get html source code with cURL

Body:
I want to get some website source code into webpage as result using php.

Here is my html code.i want to add php code to checkout website source code as result.

    <meta charset="utf-8">

        <form method="post">

Website source code

            <input type="text" name="url" placeholder="Website Url"><input type="submit" value=">>">
        </form>

Here is my php code to export html source code.

[[-- <?php $all_lines = file('example.com/');
foreach ($all_lines as $line_num => $line) {
    echo "Code.-{$line_num}: " . htmlspecialchars($line) . "\n";
} ?> --]] –

Body:
If you want to get the HTML source code of an URL, you can use cURL :

<?php
$ch = curl_init("http://www.example.com");
$html= curl_exec($ch);
curl_close($ch);
echo htmlspecialchars($html);
?>

more info here cUrl - getting the html response body and here php: Get html source code with cURL


问:
Two Columns Auto Height Background Colour
I'm probably missing something really simple here. I have two columns which keep the same height, depending on which div has more content inside of it, however the background colour does not extend on the shorter column; the columns change to a vertical layout when the display is smaller with the use of media queries. How can I get the background colour of the left column to extend to the bottom of the div?

#pageContainer {
        width: 100%;
        text-align: center;
    }

    #pageContainer p {
        line-height: 10px;
    }

    .sectionContainer {
        width: 80%;
        margin: 0 auto;
        display: table;
    }

    .leftColumn {
        display: table-cell;
        float: left;
        width: 50%;
        background-color: #4F4F4F;
        color: #FFFFFF;
    }

    .rightColumn {
        display: table-cell;
        float: left;
        width: 50%;
        background-color: #EEEEEE;
        color: #000000;

    }

    @media all and (max-width: 768px) {
        .sectionContainer {
            width: 100%;
        }

        .leftColumn {
            width: 100%;
        }

        .rightColumn {
            width: 100%;
        }
    }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="pageContainer">
  <div class="sectionContainer">
    <div class="leftColumn">
      <h1>Left Column</h1>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
    </div>
    <div class="rightColumn">
      <h1>Right Column</h1>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
    </div>
  </div>
</div></code>```

I have included a CodePen to show the problem: https://codepen.io/Macast/pen/ZaZrNz

Thanks!

答:
You can use display: flex; instead of display: table; and float: left;. That will make the children have equal height.

#pageContainer {
        width: 100%;
        text-align: center;
    }

    #pageContainer p {
        line-height: 10px;
    }

    .sectionContainer {
        width: 80%;
        margin: 0 auto;
        display: flex;
    }

    .leftColumn {
        flex-basis: 50%;
        background-color: #4F4F4F;
        color: #FFFFFF;
    }

    .rightColumn {
        flex-basis: 50%;
        background-color: #EEEEEE;
        color: #000000;

    }

    @media all and (max-width: 768px) {
        .sectionContainer {
            width: 100%;
        }

        .leftColumn {
            width: 100%;
        }

        .rightColumn {
            width: 100%;
        }
    }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="pageContainer">
  <div class="sectionContainer">
    <div class="leftColumn">
      <h1>Left Column</h1>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
    </div>
    <div class="rightColumn">
      <h1>Right Column</h1>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
    </div>
  </div>
</div></code>```

Body:
I'm probably missing something really simple here. I have two columns which keep the same height, depending on which div has more content inside of it, however the background colour does not extend on the shorter column; the columns change to a vertical layout when the display is smaller with the use of media queries. How can I get the background colour of the left column to extend to the bottom of the div?

#pageContainer {
        width: 100%;
        text-align: center;
    }

    #pageContainer p {
        line-height: 10px;
    }

    .sectionContainer {
        width: 80%;
        margin: 0 auto;
        display: table;
    }

    .leftColumn {
        display: table-cell;
        float: left;
        width: 50%;
        background-color: #4F4F4F;
        color: #FFFFFF;
    }

    .rightColumn {
        display: table-cell;
        float: left;
        width: 50%;
        background-color: #EEEEEE;
        color: #000000;

    }

    @media all and (max-width: 768px) {
        .sectionContainer {
            width: 100%;
        }

        .leftColumn {
            width: 100%;
        }

        .rightColumn {
            width: 100%;
        }
    }

Left Column

Left Column

Left Column

Left Column

Left Column

Left Column

Left Column

Left Column

Left Column

Left Column

Left Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

Right Column

I have included a CodePen to show the problem: https://codepen.io/Macast/pen/ZaZrNz

Thanks!

Body:
You can use display: flex; instead of display: table; and float: left;. That will make the children have equal height.

#pageContainer {
        width: 100%;
        text-align: center;
    }

    #pageContainer p {
        line-height: 10px;
    }

    .sectionContainer {
        width: 80%;
        margin: 0 auto;
        display: flex;
    }

    .leftColumn {
        flex-basis: 50%;
        background-color: #4F4F4F;
        color: #FFFFFF;
    }

    .rightColumn {
        flex-basis: 50%;
        background-color: #EEEEEE;
        color: #000000;

    }

    @media all and (max-width: 768px) {
        .sectionContainer {
            width: 100%;
        }

        .leftColumn {
            width: 100%;
        }

        .rightColumn {
            width: 100%;
        }
    }

<div id="pageContainer">
  <div class="sectionContainer">
    <div class="leftColumn">
      <h1>Left Column</h1>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
      <p>Left Column</p>
    </div>
    <div class="rightColumn">
      <h1>Right Column</h1>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
      <p>Right Column</p>
    </div>
  </div>
</div>