问:
Avoid object allocations during draw/layout operations error in Android
I got this error in Android Studio:

Avoid object allocations during draw/layout operations

Code:

```<code>public class cizim extends View {

    Path path = new Path();
    Paint paint = new Paint();

    public cizim (Context c){
        super(c);
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);

    }

    @Override
    protected void onDraw(Canvas canvas){
        canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));
        canvas.drawPath(path, paint);
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        float x = event.getX();
        float y = event.getY();
        path.addCircle(x, y, 10, Path.Direction.CW);
        invalidate();
        return super.onTouchEvent(event);
    }

}
</code>```

I got the error with this code:

```<code>canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));
</code>```

How can I resolve this problem?

I need your help.

答:
Drawing a view is always a heavy task because onDraw method is invoked whenever the view needs to be drawn again, so imagine allocating/creating new objects in that method; it will certainly take a lot of time and will decrease your app performance.

So instead of creating your bitmap every time onDraw is called, create it only once in your view constructor.

Add a new instance variable to your class:

```<code>public class cizim extends View {

    private Bitmap bitmap;

    ...
}
</code>```

Then in your constructor, create that object as follows:

```<code>public cizim(Context context) {
    super(context);
    paint.setColor(Color.BLACK);
    paint.setAntiAlias(true);
    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.foto);
}
</code>```

Finally modify your onDraw method to:

```<code>@Override
protected void onDraw(Canvas canvas){
    canvas.setBitmap(bitmap);
    canvas.drawPath(path, paint);
    super.onDraw(canvas);
}
</code>```

Edit:

There is actually another issue with your code that will result in UnsupportedOperationException when calling canvas.setBitmap. If you refer to the documentation, setBitmap will change the bitmap the canvas will draw to. Since you need to draw the bitmap on the screen, you cannot use setBitmap here. So what you actually need is canvas.drawBitmap

Change your onDraw method to:

```<code>@Override
protected void onDraw(Canvas canvas){
    canvas.drawBitmap(bitmap, 0, 0, paint);
    canvas.drawPath(path, paint);
    super.onDraw(canvas);
}
</code>```

Body:
I got this error in Android Studio:

Avoid object allocations during draw/layout operations

Code:

public class cizim extends View {

    Path path = new Path();
    Paint paint = new Paint();

    public cizim (Context c){
        super(c);
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);

    }

    @Override
    protected void onDraw(Canvas canvas){
        canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));
        canvas.drawPath(path, paint);
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        float x = event.getX();
        float y = event.getY();
        path.addCircle(x, y, 10, Path.Direction.CW);
        invalidate();
        return super.onTouchEvent(event);
    }

}

I got the error with this code:

canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));

How can I resolve this problem?

I need your help.

Body:
Drawing a view is always a heavy task because onDraw method is invoked whenever the view needs to be drawn again, so imagine allocating/creating new objects in that method; it will certainly take a lot of time and will decrease your app performance.

So instead of creating your bitmap every time onDraw is called, create it only once in your view constructor.

Add a new instance variable to your class:

public class cizim extends View {

    private Bitmap bitmap;

    ...
}

Then in your constructor, create that object as follows:

public cizim(Context context) {
    super(context);
    paint.setColor(Color.BLACK);
    paint.setAntiAlias(true);
    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.foto);
}

Finally modify your onDraw method to:

@Override
protected void onDraw(Canvas canvas){
    canvas.setBitmap(bitmap);
    canvas.drawPath(path, paint);
    super.onDraw(canvas);
}

Edit:

There is actually another issue with your code that will result in UnsupportedOperationException when calling canvas.setBitmap. If you refer to the documentation, setBitmap will change the bitmap the canvas will draw to. Since you need to draw the bitmap on the screen, you cannot use setBitmap here. So what you actually need is canvas.drawBitmap

Change your onDraw method to:

@Override
protected void onDraw(Canvas canvas){
    canvas.drawBitmap(bitmap, 0, 0, paint);
    canvas.drawPath(path, paint);
    super.onDraw(canvas);
}


来源: stackexchange

问:
Sisense - How To Customize UI
I'm a total Sisense noob, but am being tasked with customizing the look and feel of the Sisense app. Out of the box, it looks similar to:

For starters, I need to customize the header and left nav (highlighted in the screenshot above). I've read some of the Sisense documentation and lots of forums and posts, but am having trouble getting a straight answer to how to customize the UI. How do I modify/override the existing HTML, CSS, and JavaScript for various elements on the page? (may be 3 separate questions)

(note: Answers can include "it's actually easier to embed dashboards and widgets into your existing application")

答:
You need to have an add-on to your Sisense license to customize the sisense web app.

https://documentation.sisense.com/7-1/administration/embedded-analytics/rebranding-sisense/white-label.htm#gsc.tab=0

ContentLicense: CC BY-SA 4.0

Title: Sisense - How To Customize UI


问:
Keep options selected in multiple combobox
this is a code that generates a multiple dropdown list from a MySQL database and creates a table after clicking on a submit button with a selected option by default.

I need the table to be created when the page is loaded and also the dropdown list to keep the options selected after clicking the button.

Thanks in advance.

```<code><?php
include 'conBBDD_1.php';
$db_handle = new conBBDD();
$TourResult = $db_handle->runQuery("SELECT DISTINCT bbcTour FROM concerts ORDER BY bbcDate DESC");
?>

<form method="POST" name="Search" action="example.php">

<?php
  if (! empty($TourResult)) {
        $format = "Tour 2020";
        $select = 'selected';
        echo "<select name='tour[]' id='bb_tour' multiple='multiple'>";
   foreach ($TourResult as $key => $value) {
   echo "<option value='" . $TourResult[$key]['bbcTour']."'";
   if($TourResult[$key]['bbcTour']==$format) // to select one option only
            echo $select. ">";
        else
            echo ">";

            echo $TourResult[$key]['bbcTour'].'</option>' . "\n";
      }
    }
            echo "</select>";
?>
    <input type="submit" id="button" value="OK">
</form>
</code>```

答:
I don't quite understand the issue, but have cleaned this up for you.

If the issue is that (like your comment) you just want one item to be selected, remove the 'multiple' attribute from the select tag here.

Otherwise the 'multiple' tag and 'selected' just need to be lone strings w/ values.

<?php

  include 'conBBDD_1.php';
  $db_handle = new conBBDD();
  $TourResult = $db_handle->runQuery("SELECT DISTINCT bbcTour FROM concerts ORDER BY bbcDate DESC");

  echo '<form method="POST" name="Search" action="example.php">';

  echo "<select name='tour[]' id='bb_tour' multiple>";

  if (!empty($TourResults)) {

    $format = "Tour 2020";

    foreach ($TourResults as $Tour) {

      echo "<option value='" . $Tour . "'";

      if($Tour === $format) {

            echo ' selected';

      }

    }

    echo ">" . $Tour . "</option>\n";

  }

  echo "</select>";

  echo "</form>";

?>
```

Body:
this is a code that generates a multiple dropdown list from a MySQL database and creates a table after clicking on a submit button with a selected option by default.

I need the table to be created when the page is loaded and also the dropdown list to keep the options selected after clicking the button.

Thanks in advance.

<?php
include 'conBBDD_1.php';
$db_handle = new conBBDD();
$TourResult = $db_handle->runQuery("SELECT DISTINCT bbcTour FROM concerts ORDER BY bbcDate DESC");
?>

<form method="POST" name="Search" action="example.php">

<?php
  if (! empty($TourResult)) {
        $format = "Tour 2020";
        $select = 'selected';
        echo "<select name='tour[]' id='bb_tour' multiple='multiple'>";
   foreach ($TourResult as $key => $value) {
   echo "<option value='" . $TourResult[$key]['bbcTour']."'";
   if($TourResult[$key]['bbcTour']==$format) // to select one option only
            echo $select. ">";
        else
            echo ">";

            echo $TourResult[$key]['bbcTour'].'</option>' . "\n";
      }
    }
            echo "</select>";
?>
    <input type="submit" id="button" value="OK">
</form>


问:
NLP Sentiment Analysis net is not learning
I want to train a neural net for sentiment analysis. I have followed the tutorials on the keras webpage but I had to adapt the code to my usecase in order to be able to use the net afterwards.

For this purpose I decode back the texts from the imdb dataset from keras from numbers to text, and then I stemmize the text because I need to use the text stemmized. After that, since I want to control the way I am doing the word embeddings rather than using text_to_sequences an pad_sequences I am training a doc2vec embeddings and I am using it on the training set, so that I can obtain the embeddings from the text I want to classify.

The problem is that, the net does not learn anything, the accuracy does not improve and I can not reduce the loss function. I have tried many many things, like the architecture of the net, all the hyperparameters and changing the last layer from 2 nets to 1 and from sparse_categorical_entropy to binary_crossentropy. Let's see if anybody can help and show some light to my problem. I plug the code here and thanks in advance.

```<code>from keras.datasets import imdb
max_features = 40000
(training_data, training_targets), (testing_data, testing_targets) = imdb.load_data(num_words=max_features)

import numpy as np
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)

index = imdb.get_word_index()
reverse_index = dict([(value, key) for (key, value) in index.items()])
decoded = " ".join([reverse_index.get(i - 3, "") for i in data[0]])

import nltk
from nltk .stem import LancasterStemmer

toke_corpus = list()
lan = LancasterStemmer()

from tqdm import tqdm
lista_reviews = list()

for review in tqdm(data):
  lista_reviews.append(np.array([lan.stem(reverse_index.get(i - 3, '')) for i in review][1:]))

train_x, test_x = lista_reviews[10000:], lista_reviews[:10000]
train_y, test_y = targets[10000:], targets[:10000]

 from gensim.models.callbacks import CallbackAny2Vec

 class EpochLogger(CallbackAny2Vec):
     '''Callback to log information about training'''
     def __init__(self):
         self.epoch = 0
     def on_epoch_begin(self, model):
         print("Epoch #{} start".format(self.epoch))
     def on_epoch_end(self, model):
         print("Epoch #{} end".format(self.epoch))
         self.epoch += 1

from gensim.models.doc2vec import Doc2Vec, TaggedDocument

documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(lista_reviews)]
print("DOcuments already built")
epoch_logger = EpochLogger()
model = Doc2Vec(documents, vector_size=512, window=5, min_count=3, workers=8, epochs = 7, callbacks=[epoch_logger])

encoded_x_train, encoded_x_test = list(), list()
from tqdm import tqdm
for i in tqdm(train_x):
    encoded_x_train.append(model.infer_vector(i))
for k in tqdm(test_x):
    encoded_x_test.append(model.infer_vector(k))

import keras

reduce_lr = keras.callbacks.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.50, patience=2, verbose=1, mode='auto', cooldown=0, min_lr=0.00001)

early = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=4, verbose=1, mode='auto')

from keras import models
from keras.models import Sequential
from keras import layers
from keras.layers import Embedding, Bidirectional, Dense, LSTM, Conv1D, MaxPooling1D, Flatten

model1 = Sequential()
model1.add(Embedding(input_dim = max_features, input_length=512, output_dim=128, trainable=False))

model1.add(Conv1D(filters=64,
                 kernel_size=5,
                 padding='valid',
                 activation='linear',
                 strides=1))
model1.add(MaxPooling1D(pool_size=4))
model1.add(Dense(64, activation='linear'))
model1.add(LSTM(32, activation='tanh'))
# model1.add(Dense(32, activation='relu'))
# model1.add(Flatten())
# model1.add(Dense(1, activation='sigmoid'))
model1.add(Dense(2, activation='softmax'))
model1.summary()

from keras import optimizers
# sgd = optimizers.SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)
adam = optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, amsgrad=False)

model1.compile(loss='sparse_categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

history  = model1.fit( np.array(encoded_x_train), np.array(train_y),
 epochs= 20,
 batch_size = 500,
 validation_data = (np.array(encoded_x_test), np.array(test_y)), callbacks = [reduce_lr, early]
)
</code>```

答:
You use Doc2Vec to create sample embeddings. for this reason, I don't think that Embedding, Conv1D and MaxPooling1D layers are useful in your network. they are useful for word2vec where you can extract embeddings of each token and use them inside a network.

try to feed your network directly with your embedding in this way

```<code>model1 = Sequential()
model1.add(Dense(128, activation='relu', input_shape=(512,)))
# ....
model1.add(Dense(2, activation='softmax'))

adam = optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, amsgrad=False)

model1.compile(loss='sparse_categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

history  = model1.fit( np.array(encoded_x_train), np.array(train_y),
 epochs= 20,
 batch_size = 500,
 validation_data = (np.array(encoded_x_test), np.array(test_y)), callbacks = [reduce_lr, early]
)
</code>```

Body:
I want to train a neural net for sentiment analysis. I have followed the tutorials on the keras webpage but I had to adapt the code to my usecase in order to be able to use the net afterwards.

For this purpose I decode back the texts from the imdb dataset from keras from numbers to text, and then I stemmize the text because I need to use the text stemmized. After that, since I want to control the way I am doing the word embeddings rather than using text_to_sequences an pad_sequences I am training a doc2vec embeddings and I am using it on the training set, so that I can obtain the embeddings from the text I want to classify.

The problem is that, the net does not learn anything, the accuracy does not improve and I can not reduce the loss function. I have tried many many things, like the architecture of the net, all the hyperparameters and changing the last layer from 2 nets to 1 and from sparse_categorical_entropy to binary_crossentropy. Let's see if anybody can help and show some light to my problem. I plug the code here and thanks in advance.

from keras.datasets import imdb
max_features = 40000
(training_data, training_targets), (testing_data, testing_targets) = imdb.load_data(num_words=max_features)

import numpy as np
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)

index = imdb.get_word_index()
reverse_index = dict([(value, key) for (key, value) in index.items()])
decoded = " ".join([reverse_index.get(i - 3, "") for i in data[0]])

import nltk
from nltk .stem import LancasterStemmer

toke_corpus = list()
lan = LancasterStemmer()

from tqdm import tqdm
lista_reviews = list()

for review in tqdm(data):
  lista_reviews.append(np.array([lan.stem(reverse_index.get(i - 3, '')) for i in review][1:]))

train_x, test_x = lista_reviews[10000:], lista_reviews[:10000]
train_y, test_y = targets[10000:], targets[:10000]

 from gensim.models.callbacks import CallbackAny2Vec

 class EpochLogger(CallbackAny2Vec):
     '''Callback to log information about training'''
     def __init__(self):
         self.epoch = 0
     def on_epoch_begin(self, model):
         print("Epoch #{} start".format(self.epoch))
     def on_epoch_end(self, model):
         print("Epoch #{} end".format(self.epoch))
         self.epoch += 1

from gensim.models.doc2vec import Doc2Vec, TaggedDocument

documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(lista_reviews)]
print("DOcuments already built")
epoch_logger = EpochLogger()
model = Doc2Vec(documents, vector_size=512, window=5, min_count=3, workers=8, epochs = 7, callbacks=[epoch_logger])

encoded_x_train, encoded_x_test = list(), list()
from tqdm import tqdm
for i in tqdm(train_x):
    encoded_x_train.append(model.infer_vector(i))
for k in tqdm(test_x):
    encoded_x_test.append(model.infer_vector(k))

import keras

reduce_lr = keras.callbacks.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.50, patience=2, verbose=1, mode='auto', cooldown=0, min_lr=0.00001)

early = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=4, verbose=1, mode='auto')

from keras import models
from keras.models import Sequential
from keras import layers
from keras.layers import Embedding, Bidirectional, Dense, LSTM, Conv1D, MaxPooling1D, Flatten

model1 = Sequential()
model1.add(Embedding(input_dim = max_features, input_length=512, output_dim=128, trainable=False))

model1.add(Conv1D(filters=64,
                 kernel_size=5,
                 padding='valid',
                 activation='linear',
                 strides=1))
model1.add(MaxPooling1D(pool_size=4))
model1.add(Dense(64, activation='linear'))
model1.add(LSTM(32, activation='tanh'))
# model1.add(Dense(32, activation='relu'))
# model1.add(Flatten())
# model1.add(Dense(1, activation='sigmoid'))
model1.add(Dense(2, activation='softmax'))
model1.summary()

from keras import optimizers
# sgd = optimizers.SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)
adam = optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, amsgrad=False)

model1.compile(loss='sparse_categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

history  = model1.fit( np.array(encoded_x_train), np.array(train_y),
 epochs= 20,
 batch_size = 500,
 validation_data = (np.array(encoded_x_test), np.array(test_y)), callbacks = [reduce_lr, early]
)

Body:
You use Doc2Vec to create sample embeddings. for this reason, I don't think that Embedding, Conv1D and MaxPooling1D layers are useful in your network. they are useful for word2vec where you can extract embeddings of each token and use them inside a network.

try to feed your network directly with your embedding in this way

model1 = Sequential()
model1.add(Dense(128, activation='relu', input_shape=(512,)))
# ....
model1.add(Dense(2, activation='softmax'))

adam = optimizers.Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, amsgrad=False)

model1.compile(loss='sparse_categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

history  = model1.fit( np.array(encoded_x_train), np.array(train_y),
 epochs= 20,
 batch_size = 500,
 validation_data = (np.array(encoded_x_test), np.array(test_y)), callbacks = [reduce_lr, early]
)


问:
Difference between these two requests
Request One  (Not working)

```<code>{
    "AddNewRequest":{
        "Patient":{
            "PrimaryPhoneNumber":" ",
            "DateOfBirth":" ",
            "CellPhoneNumber1":" ",
            "ResidentialAddress":{
                "AddressLine1":" ",
                "State":" ",
                "City":" ",
                "PostalCode":" "
            },
            "PhoneNumber1":" ",
            "SSN":" ",
            "FullName":"John",
            "Religion":" ",
            "Gender":" ",
            "Race":" ",
            "Firstname":"Vinoth",
            "EmailAddress1":" ",
            "LastName":"Cooper"
        },
        "Header":{
            "SourceSiteID":"300242",
            "DestinationSiteID":"300242",
            "PrimeSuiteUserID":"1"
        },
        "Credentials":{
            "VendorCredential":{
                "VendorLogin":"testGUID",
                "VendorPassword":"testGUID"
            },
            "PrimeSuiteCredential":{
                "PrimeSuiteUserPassword":"password",
                "PrimeSuiteSiteId":"1",
                "PrimeSuiteUserName":"Admin"
            }
        }
    }
}
</code>```

Request Two (Working)

```<code>{
    "PatientAddNewRequest":{
        "Credentials":{
            "PrimeSuiteCredential":{
                "PrimeSuiteSiteId":"300242",
                "PrimeSuiteUserName":"Admin",
                "PrimeSuiteUserPassword":"password"
            },
            "VendorCredential":{
                "VendorLogin":"testGUID",
                "VendorPassword":"testGUID"
            }
        },
        "Header":{
            "DestinationSiteID":"300242",
            "PrimeSuiteUserID":"1",
            ":SourceSiteID":"300242"
        },
        "Patient":{
            "CellPhoneNumber1":"206-567-2222",
            "DateOfBirth":"/Date(1306348200000)/",
            "EmailAddress1":"JohnDoe@yahoo.com",
            "Firstname":"TestMan1",
            "FullName":"TestFullMan1",
            "Gender":"2",
            "LastName":"Testlastname1",
            "PhoneNumber1":"205-567-1111",
            "PrimaryPhoneNumber":"205-456-4545",
            "Race":"2",
            "Religion":"3",
            "ResidentialAddress":{
                "City":"Carrollton",
                "PostalCode":"35209",
                "State":"10"
            },
            "SSN":"911-91-9191"
        }
    }
}
</code>```

I am just not able to figure out why the first request is not working and the second one gives response. Can anyone identify what i am doing wrong.

Does Order Matter?

Update

The First one throws me Bad Request and the second one responds as expected.

答:
In JSON the order doesn't matter but the name does. In the Request One you have "AddNewRequest" while in Request Two you have "PatientAddNewRequest".

Also on the server side, the serializer/de-serializer may need specific ordering.

JSON

An object is an unordered
  collection of zero or more name/value
  pairs, where a name is a string and a
  value is a string, number,    boolean,
  null, object, or array.

ContentLicense: CC BY-SA 3.0

Title: Difference between these two requests

Body:
Request One  (Not working)

{
    "AddNewRequest":{
        "Patient":{
            "PrimaryPhoneNumber":" ",
            "DateOfBirth":" ",
            "CellPhoneNumber1":" ",
            "ResidentialAddress":{
                "AddressLine1":" ",
                "State":" ",
                "City":" ",
                "PostalCode":" "
            },
            "PhoneNumber1":" ",
            "SSN":" ",
            "FullName":"John",
            "Religion":" ",
            "Gender":" ",
            "Race":" ",
            "Firstname":"Vinoth",
            "EmailAddress1":" ",
            "LastName":"Cooper"
        },
        "Header":{
            "SourceSiteID":"300242",
            "DestinationSiteID":"300242",
            "PrimeSuiteUserID":"1"
        },
        "Credentials":{
            "VendorCredential":{
                "VendorLogin":"testGUID",
                "VendorPassword":"testGUID"
            },
            "PrimeSuiteCredential":{
                "PrimeSuiteUserPassword":"password",
                "PrimeSuiteSiteId":"1",
                "PrimeSuiteUserName":"Admin"
            }
        }
    }
}

Request Two (Working)

{
    "PatientAddNewRequest":{
        "Credentials":{
            "PrimeSuiteCredential":{
                "PrimeSuiteSiteId":"300242",
                "PrimeSuiteUserName":"Admin",
                "PrimeSuiteUserPassword":"password"
            },
            "VendorCredential":{
                "VendorLogin":"testGUID",
                "VendorPassword":"testGUID"
            }
        },
        "Header":{
            "DestinationSiteID":"300242",
            "PrimeSuiteUserID":"1",
            ":SourceSiteID":"300242"
        },
        "Patient":{
            "CellPhoneNumber1":"206-567-2222",
            "DateOfBirth":"/Date(1306348200000)/",
            "EmailAddress1":"JohnDoe@yahoo.com",
            "Firstname":"TestMan1",
            "FullName":"TestFullMan1",
            "Gender":"2",
            "LastName":"Testlastname1",
            "PhoneNumber1":"205-567-1111",
            "PrimaryPhoneNumber":"205-456-4545",
            "Race":"2",
            "Religion":"3",
            "ResidentialAddress":{
                "City":"Carrollton",
                "PostalCode":"35209",
                "State":"10"
            },
            "SSN":"911-91-9191"
        }
    }
}

I am just not able to figure out why the first request is not working and the second one gives response. Can anyone identify what i am doing wrong.

Does Order Matter?

Update

The First one throws me Bad Request and the second one responds as expected.


问:
How to delete a contact from a phonebook program
I made a phonebook program which includes Add and search a contact.

But when I made the delete function, it deleted all the contacts instead of the one I entered.

I know it's a little bit complicated but any ideas?

This is the input in phonebook.txt from which I want to delete a contact:

```<code>Barney Hackett      0114543053
Luis Avery      01056633489
Hudson Ramsay       01576633982
</code>```

Ihe code is:

```<code>void DeletePhoneNumber() {
    FILE* search, * fp1;
    //to receive the enter from system("cls")
    char temp;
    scanf("%c", &temp);
    search = fopen("PHONEBOOK.txt", "r+");
    fp1 = fopen("temp.txt", "w");
    system("cls");
    printf("\t*****DELETE CONTACT*****");
    printf("\n\t Enter Name: ");
    int length;
    length = strlen(SearchName);
    int i, y = 0;
    //string comparison//
    while (fgets(name, 50, search) != NULL) {
                fputs(name, fp1);
            }
            fclose(search);
            fclose(fp1);
            search = fopen("PHONEBOOK.txt", "w");
            fp1 = fopen("temp.txt", "r");
            while (fgets(name, 50, search) != NULL) {

                fputs(name, search);
            }
            fclose(search);
            fclose(fp1);
            remove("temp.txt");
            printf("\n\tPRESS ANY KEY TO CONTINUE");
            getch();
            MainMenu();
        }
    }
</code>```

答:
I'll use this "answer" space to give you a partial analysis of your code. You can use it to improve your code.

Basically, your loop is all wrong:

```<code>search = fopen("PHONEBOOK.txt", "r+");
while (fgets(name, 50, search) != NULL) {
    // ...
    while (token != NULL) {
        // ...
        fclose(search);
        search = fopen("PHONEBOOK.txt", "w");
</code>```

You opened the file in append mode, read from it and now close the file, to open it in a different mode. What will it read on the next fgets in the while loop?

Opening the file in mode "w" for writing will destroy the file. So here is why there are no more entries in your file.

```<code>        fclose(search);
        MainMenu();
</code>```

At the bottom of the loop you close the file. How can it still read something with fgets in the while loop.

Next you call MainMenu. But I assume this function calls this DeletePhoneNumber function, so you are in a strange loop/recursion. Of course, when you are done with deleting the phone number, you simply return to the main menu, not call it again.

Body:
I made a phonebook program which includes Add and search a contact.

But when I made the delete function, it deleted all the contacts instead of the one I entered.

I know it's a little bit complicated but any ideas?

This is the input in phonebook.txt from which I want to delete a contact:

Barney Hackett      0114543053
Luis Avery      01056633489
Hudson Ramsay       01576633982

Ihe code is:

void DeletePhoneNumber() {
    FILE* search, * fp1;
    //to receive the enter from system("cls")
    char temp;
    scanf("%c", &temp);
    search = fopen("PHONEBOOK.txt", "r+");
    fp1 = fopen("temp.txt", "w");
    system("cls");
    printf("\t*****DELETE CONTACT*****");
    printf("\n\t Enter Name: ");
    int length;
    length = strlen(SearchName);
    int i, y = 0;
    //string comparison//
    while (fgets(name, 50, search) != NULL) {
                fputs(name, fp1);
            }
            fclose(search);
            fclose(fp1);
            search = fopen("PHONEBOOK.txt", "w");
            fp1 = fopen("temp.txt", "r");
            while (fgets(name, 50, search) != NULL) {

                fputs(name, search);
            }
            fclose(search);
            fclose(fp1);
            remove("temp.txt");
            printf("\n\tPRESS ANY KEY TO CONTINUE");
            getch();
            MainMenu();
        }
    }

Body:
I'll use this "answer" space to give you a partial analysis of your code. You can use it to improve your code.

Basically, your loop is all wrong:

search = fopen("PHONEBOOK.txt", "r+");
while (fgets(name, 50, search) != NULL) {
    // ...
    while (token != NULL) {
        // ...
        fclose(search);
        search = fopen("PHONEBOOK.txt", "w");

You opened the file in append mode, read from it and now close the file, to open it in a different mode. What will it read on the next fgets in the while loop?

Opening the file in mode "w" for writing will destroy the file. So here is why there are no more entries in your file.

        fclose(search);
        MainMenu();

At the bottom of the loop you close the file. How can it still read something with fgets in the while loop.

Next you call MainMenu. But I assume this function calls this DeletePhoneNumber function, so you are in a strange loop/recursion. Of course, when you are done with deleting the phone number, you simply return to the main menu, not call it again.


问:
urc_id_SEQ.nextval gives invalid identifier error?
I have created a sequence but it gives me invalid identifier error. I am running  select urc_id_SEQ.nextval from dual;</p>

答:
Rebuild the sequence without using double quotes in the command. If you use double-quotes it makes the name case sensitive and then you must always use double quotes to reference the object. Eliminating the quotes keeps the object name case-insensitive.

```<code>CREATE SEQUENCE A.urc_id_SEQ MINVALUE 1 MAXVALUE 9999999999 INCREMENT BY 1 START WITH 1 NOCACHE ORDER NOCYCLE;
</code>```

Body:
Rebuild the sequence without using double quotes in the command. If you use double-quotes it makes the name case sensitive and then you must always use double quotes to reference the object. Eliminating the quotes keeps the object name case-insensitive.

CREATE SEQUENCE A.urc_id_SEQ MINVALUE 1 MAXVALUE 9999999999 INCREMENT BY 1 START WITH 1 NOCACHE ORDER NOCYCLE;


问:
Angular Material - table mat-table not rendering data from rest api
I have been trying to implement mat-table in angular 8.
I don't understand what I'm doing wrong, the data which is being provided by my REST endpoint is clearly visible on the console output.

my admin.component.html file

```<code>    <table mat-table [dataSource]="dataSource">
        <!-- <ng-container *ngFor="let value of values;let i=index;">
            <tr *ngFor ="let row of {{value.rows}};let i = index;">
                <th mat-header-cell *matHeaderCellDef>{{row.header}}</th>
                <td mat-cell>{{}}</td>
            </tr>
        </ng-container> -->

        <ng-container matColumnDef="position">
                <th mat-header-cell *matHeaderCellDef> No.</th>
                <td mat-cell *matCellDef="let data"> {{data.position}} </td>
              </ng-container>

        <ng-container matColumnDef="USERNAME">
                <th mat-header-cell *matHeaderCellDef> USERNAME</th>
                <td mat-cell *matCellDef="let data"> {{data.username}} </td>
              </ng-container>

              <!-- Name Column -->
              <ng-container matColumnDef="BU">
                <th mat-header-cell *matHeaderCellDef> BU</th>
                <td mat-cell *matCellDef="let data"> {{data.BU}} </td>
              </ng-container>

              <!-- Weight Column -->
              <ng-container matColumnDef="DURATION">
                <th mat-header-cell *matHeaderCellDef> DURATION </th>
                <td mat-cell *matCellDef="let data"> {{data.duration}} </td>
              </ng-container>

              <!-- Symbol Column -->
              <ng-container matColumnDef="PURPOSE">
                <th mat-header-cell *matHeaderCellDef> PURPOSE</th>
                <td mat-cell *matCellDef="let data"> {{data.remarks}} </td>
              </ng-container>
              <ng-container matColumnDef="apr">
                    <th mat-header-cell *matHeaderCellDef>
                         <mat-checkbox (change)="$event ? masterToggle() : null"
                                        [checked]="selection.hasValue() && isAllSelected()"
                                        [indeterminate]="selection.hasValue() && !isAllSelected()"
                                        [aria-label]="checkboxLabel()">
                                APPROVE</mat-checkbox></th>
                    <td mat-cell *matCellDef="let row" >
                            <mat-checkbox (click)="$event.stopPropagation()"
                                          (change)="$event ? selection.toggle(row) : null"
                                            [checked]="selection.isSelected(row)"
                                            [aria-label]="checkboxLabel(row)">Approve</mat-checkbox>
                    </td>
                  </ng-container>

                  <ng-container matColumnDef="rej">
                        <th mat-header-cell *matHeaderCellDef> REJECT</th>
                        <td mat-cell *matCellDef="let row" >
                                <mat-checkbox >Reject</mat-checkbox>
                        </td>
                      </ng-container>

              <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
              <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
              <!-- <tr mat-footer-row *matFooterRowDef><button mat-button> Submit</button></tr> -->
            </table>
            <button mat-button color="primary" (click)="OnApprovalSubmit()">Submit</button>

</code>```

my ts file

```<code>export interface UserData{
  position:number;
  username:any;
  BU:any;
  duration:any;
  remarks:string;

}

@Component({
  selector: 'app-admin',
  templateUrl: 'admin.component.html',
  styleUrls: ['./app.component.css']
})

export class AdminComponent implements OnInit{
  displayedColumns: string[] = ['position','USERNAME', 'BU', 'DURATION', 'PURPOSE','apr','rej'];
  USER_DATA:any;

  // approve:any;
  // reject:any;

  constructor(public testService : TestService){}
  ngOnInit(){
    this.testService.getUserAccessDetails().subscribe(data =>{
      console.log(data);
      this.USER_DATA=data.USER_DATA;
      console.log(this.USER_DATA);

    })

  }

  dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
  // console.log(this.USER_DATA);
  selection = new SelectionModel<UserData>(true, []);

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  /** Selects all rows if they are not all selected; otherwise clear selection. */
  masterToggle() {
    console.log(this.USER_DATA);
    this.isAllSelected() ?
        this.selection.clear() :
        this.dataSource.data.forEach(row => this.selection.select(row));
  }

  /** The label for the checkbox on the passed row */
  checkboxLabel(row?: UserData): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
  }

}

</code>```

when the console data it is coming in this format

```<code>USER_DATA: Array(1)
0: {position: "01", username: "NAme", BU: "Team", Duration: 3, remarks: "NA"}
</code>```

but still no rows are getting rendered and there is no error also.
Any help on this would be appreciated.

答:
You need to provide the result obtained as 'dataSource' inside the subscribe, since it is the dataSource provided as an input to the mat-table.</p>

```<code>ngOnInit() {
    this.testService.getUserAccessDetails()
    .subscribe(data => {
         this.USER_DATA=data.USER_DATA;
         this.dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
    });
}
</code>```

Body:
I have been trying to implement mat-table in angular 8.
I don't understand what I'm doing wrong, the data which is being provided by my REST endpoint is clearly visible on the console output.

my admin.component.html file

        <ng-container matColumnDef="position">
                 No.
                 {{data.position}}
              </ng-container>

        <ng-container matColumnDef="USERNAME">
                 USERNAME
                 {{data.username}}
              </ng-container>

              <ng-container matColumnDef="BU">
                 BU
                 {{data.BU}}
              </ng-container>

              <ng-container matColumnDef="DURATION">
                 DURATION
                 {{data.duration}}
              </ng-container>

              <ng-container matColumnDef="PURPOSE">
                 PURPOSE
                 {{data.remarks}}
              </ng-container>
              <ng-container matColumnDef="apr">

                         <mat-checkbox (change)="$event ? masterToggle() : null"
                                        [checked]="selection.hasValue() && isAllSelected()"
                                        [indeterminate]="selection.hasValue() && !isAllSelected()"
                                        [aria-label]="checkboxLabel()">
                                APPROVE</mat-checkbox>

                            <mat-checkbox (click)="$event.stopPropagation()"
                                          (change)="$event ? selection.toggle(row) : null"
                                            [checked]="selection.isSelected(row)"
                                            [aria-label]="checkboxLabel(row)">Approve</mat-checkbox>

                  </ng-container>

                  <ng-container matColumnDef="rej">
                         REJECT

                                <mat-checkbox >Reject</mat-checkbox>

                      </ng-container>

            <button mat-button color="primary" (click)="OnApprovalSubmit()">Submit</button>

my ts file

export interface UserData{
  position:number;
  username:any;
  BU:any;
  duration:any;
  remarks:string;

}

@Component({
  selector: 'app-admin',
  templateUrl: 'admin.component.html',
  styleUrls: ['./app.component.css']
})

export class AdminComponent implements OnInit{
  displayedColumns: string[] = ['position','USERNAME', 'BU', 'DURATION', 'PURPOSE','apr','rej'];
  USER_DATA:any;

  // approve:any;
  // reject:any;

  constructor(public testService : TestService){}
  ngOnInit(){
    this.testService.getUserAccessDetails().subscribe(data =>{
      console.log(data);
      this.USER_DATA=data.USER_DATA;
      console.log(this.USER_DATA);

    })

  }

  dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
  // console.log(this.USER_DATA);
  selection = new SelectionModel<UserData>(true, []);

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  /** Selects all rows if they are not all selected; otherwise clear selection. */
  masterToggle() {
    console.log(this.USER_DATA);
    this.isAllSelected() ?
        this.selection.clear() :
        this.dataSource.data.forEach(row => this.selection.select(row));
  }

  /** The label for the checkbox on the passed row */
  checkboxLabel(row?: UserData): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
  }

}

when the console data it is coming in this format

USER_DATA: Array(1)
0: {position: "01", username: "NAme", BU: "Team", Duration: 3, remarks: "NA"}

but still no rows are getting rendered and there is no error also.
Any help on this would be appreciated.

Body:
You need to provide the result obtained as 'dataSource' inside the subscribe, since it is the dataSource provided as an input to the mat-table.

ngOnInit() {
    this.testService.getUserAccessDetails()
    .subscribe(data => {
         this.USER_DATA=data.USER_DATA;
         this.dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
    });
}


问:
Lint discrepancies between different machines
I have a multi module android app which has lint configured to run prior to pushing to github, as a pre-push hook. I have 2 different machines (both Mac) which I use to write code for this app.

On one machine lint flags an error due to Missing Permissions. The permission that lint is looking for is declared in a different module and the app compiles, builds and runs as expected, so this being done correctly is not in question. I'm also part of a team of 5 and no one else sees this.

```<code><?xml version="1.0" encoding="UTF-8"?>
<issues format="5" by="lint 3.6.2">

<issue
    id="MissingPermission"
    severity="Error"
    message="Missing permissions required by TelephonyManager.getNetworkType: android.permission.READ_PHONE_STATE"
    category="Correctness"
    priority="9"
    summary="Missing Permissions"
    explanation="This check scans through your code and libraries and looks at the APIs being used, and checks this against the set of permissions required to access those APIs. If the code using those APIs is called at runtime, then the program will crash.\n\nFurthermore, for permissions that are revocable (with targetSdkVersion 23), client code must also be prepared to handle the calls throwing an exception if the user rejects the request for permission at runtime."
    errorLine1="    return when (telephonyManager.networkType) {"
    errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
    <location
        file="/Users/chris/myproject/dependencies/network/CellularInfoImpl.kt"
        line="47"
        column="18"/>
</issue>
</code>```

I've checked the following list to ensure that both machines are running the same configuration.

Android Studio version.

It's the same code base on the same branch.

Gradle plugin version

gradle.properties

gradle-wrapper.properties

Android Studios preferences for Correctness Inspections. (Missing permissions is ticked on both)

lint config.xml

lint version, taken from the lint report after completing the gradle task.

My question is, what else could be causing the discrepancy? Where else should I be looking to attempt to resolve this?

Thanks.

答: The simple solution is to add a SuppressWarning annotation for Missing Permissions. This overcomes the problem by stopping the lint warnings, but doesn't actually solve it.</p>

Body:
I have a multi module android app which has lint configured to run prior to pushing to github, as a pre-push hook. I have 2 different machines (both Mac) which I use to write code for this app.

On one machine lint flags an error due to Missing Permissions. The permission that lint is looking for is declared in a different module and the app compiles, builds and runs as expected, so this being done correctly is not in question. I'm also part of a team of 5 and no one else sees this.

<?xml version="1.0" encoding="UTF-8"?>
<issues format="5" by="lint 3.6.2">

<issue
    id="MissingPermission"
    severity="Error"
    message="Missing permissions required by TelephonyManager.getNetworkType: android.permission.READ_PHONE_STATE"
    category="Correctness"
    priority="9"
    summary="Missing Permissions"
    explanation="This check scans through your code and libraries and looks at the APIs being used, and checks this against the set of permissions required to access those APIs. If the code using those APIs is called at runtime, then the program will crash.

Furthermore, for permissions that are revocable (with targetSdkVersion 23), client code must also be prepared to handle the calls throwing an exception if the user rejects the request for permission at runtime."
    errorLine1="    return when (telephonyManager.networkType) {"
    errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
    <location
        file="/Users/chris/myproject/dependencies/network/CellularInfoImpl.kt"
        line="47"
        column="18"/>
</issue>

I've checked the following list to ensure that both machines are running the same configuration.

Android Studio version.

It's the same code base on the same branch.

Gradle plugin version

gradle.properties

gradle-wrapper.properties

Android Studios preferences for Correctness Inspections. (Missing permissions is ticked on both)

lint config.xml

lint version, taken from the lint report after completing the gradle task.

My question is, what else could be causing the discrepancy? Where else should I be looking to attempt to resolve this?

Thanks.


问:
Azure blob upload with content-md5 set
Goal: Upload a file to Azure Blob Storage and set MD5 that can be validated when a  user downloads the file.

Using Azure CLI Powershell.

```<code>Get-FileHash -Algorithm MD5 .\AutoSetup.zip
Algorithm       Hash                                             Path
---------       ----                                             ----
MD5             693EF0DB938308AC2C362F50F7CB9F9F                 C:\MyFiles\AutoSetup.zip

az storage blob upload --account-name mystorageaccount --container-name mycontainername --file AutoSetup.zip --name Autosetup2.zip --content-md5 693EF0DB938308AC2C362F50F7CB9F9F
Finished[#############################################################]  100.0000%
The MD5 value specified in the request is invalid. MD5 value must be 128 bits and base64 encoded. ErrorCode: InvalidMd5
<?xml version="1.0" encoding="utf-8"?><Error><Code>InvalidMd5</Code><Message>The MD5 value specified in the request is invalid. MD5 value must be 128 bits and base64 encoded.
RequestId:9f27334a-801e-0028-6db4-3539c5000000
Time:2020-05-29T12:28:23.7677258Z</Message></Error>
</code>```

Edit 1:

I've also attempted getting the hash this way

```<code>$someFilePath = "C:\MyFiles\AutoSetup.zip"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
Write-Host $hash
69-3E-F0-DB-93-83-08-AC-2C-36-2F-50-F7-CB-9F-9F
</code>```

It seems that no matter what I do, the MD5 that is returned for the file is 693EF0DB938308AC2C362F50F7CB9F9F but Azure won't take it...

Edit 2:

I've generated a random 128-bit string $B&E)H@McQfTjWnZ and proceeded to encode it in Base64 which gave me JEImRSlIQE1jUWZUalduWg== When I attempt to upload a blob with THAT hash, I get a different error message:

```<code>The MD5 value specified in the request did not match with the MD5 value calculated by the server. ErrorCode: Md5Mismatch
</code>```

The above makes sense, cause I just created a random 128 bit base64 encoded hash. However, now I am wondering why the Powershell's Get-FileHash command gives me what seems to be incorrect?

What can be causing the error?

答:
Try converting the hash into a Base64 encoded string. Something like:</p>

```<code>$someFilePath = "C:\MyFiles\AutoSetup.zip"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.Convert]::ToBase64String($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
Write-Host $hash
8SzzdVQAV4Wdbp8Z9qsczg==
</code>```

Title: Azure blob upload with content-md5 set

Body:
Goal: Upload a file to Azure Blob Storage and set MD5 that can be validated when a  user downloads the file.

Using Azure CLI Powershell.

Get-FileHash -Algorithm MD5 .\AutoSetup.zip
Algorithm       Hash                                             Path
---------       ----                                             ----
MD5             693EF0DB938308AC2C362F50F7CB9F9F                 C:\MyFiles\AutoSetup.zip

az storage blob upload --account-name mystorageaccount --container-name mycontainername --file AutoSetup.zip --name Autosetup2.zip --content-md5 693EF0DB938308AC2C362F50F7CB9F9F
Finished[#############################################################]  100.0000%
The MD5 value specified in the request is invalid. MD5 value must be 128 bits and base64 encoded. ErrorCode: InvalidMd5
<?xml version="1.0" encoding="utf-8"?><Error>InvalidMd5<Message>The MD5 value specified in the request is invalid. MD5 value must be 128 bits and base64 encoded.
RequestId:9f27334a-801e-0028-6db4-3539c5000000
Time:2020-05-29T12:28:23.7677258Z</Message></Error>

Edit 1:

I've also attempted getting the hash this way

$someFilePath = "C:\MyFiles\AutoSetup.zip"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
Write-Host $hash
69-3E-F0-DB-93-83-08-AC-2C-36-2F-50-F7-CB-9F-9F

It seems that no matter what I do, the MD5 that is returned for the file is 693EF0DB938308AC2C362F50F7CB9F9F but Azure won't take it...

Edit 2:

I've generated a random 128-bit string $B&E)H@McQfTjWnZ and proceeded to encode it in Base64 which gave me JEImRSlIQE1jUWZUalduWg== When I attempt to upload a blob with THAT hash, I get a different error message:

The MD5 value specified in the request did not match with the MD5 value calculated by the server. ErrorCode: Md5Mismatch

The above makes sense, cause I just created a random 128 bit base64 encoded hash. However, now I am wondering why the Powershell's Get-FileHash command gives me what seems to be incorrect?

What can be causing the error?

Body:
Try converting the hash into a Base64 encoded string. Something like:

$someFilePath = "C:\MyFiles\AutoSetup.zip"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.Convert]::ToBase64String($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
Write-Host $hash
8SzzdVQAV4Wdbp8Z9qsczg==


问:
Pass an object as a global variable in js from gs
I am working with Google Apps Script to build a web application.
I have a function in google app script:

```<code>function getPalette(){
  var ss = SpreadsheetApp.openByUrl(url);
  var ws_palette = ss.getSheetByName("palette");
  var palette_data = ws_palette.getRange(2,1,1,1).getValue();
  var palette = JSON.parse(palette_data.replace(/'/g, '"'));
  return palette;
}
</code>```

I want to pass this palette object to javascript.html as a global variable.

How can I do that? Many thanks!

答:
Apps Script side variables are accessible from the html/javascript side by scriptlets

Scriptlets allow you to run any Apps Script code with <? ... ?> or access any variable from code.gs with <?= ... ?> within the html or javascript part or your WebApp.

Sample for accessing global variables:

Code.gs

```<code>const globalVar = "I am global";

function doGet() {
  return HtmlService.createTemplateFromFile("javascript").evaluate();
}
</code>```

javascript.html

```<code><!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <script>
    console.log(<?= globalVar ?>);
    </script>
  </body>
</html>
</code>```

Important:

Apps Script scriptlets will only work if you return your html content by creating and evaluating a template rather than directly creating an output.

Body:
I am working with Google Apps Script to build a web application.
I have a function in google app script:

function getPalette(){
  var ss = SpreadsheetApp.openByUrl(url);
  var ws_palette = ss.getSheetByName("palette");
  var palette_data = ws_palette.getRange(2,1,1,1).getValue();
  var palette = JSON.parse(palette_data.replace(/'/g, '"'));
  return palette;
}

I want to pass this palette object to javascript.html as a global variable.

How can I do that? Many thanks!

Body:
Apps Script side variables are accessible from the html/javascript side by scriptlets

Scriptlets allow you to run any Apps Script code with <? ... ?> or access any variable from code.gs with <?= ... ?> within the html or javascript part or your WebApp.

Sample for accessing global variables:

Code.gs

const globalVar = "I am global";

function doGet() {
  return HtmlService.createTemplateFromFile("javascript").evaluate();
}

javascript.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <script>
    console.log(<?= globalVar ?>);
    </script>
  </body>
</html>

Important:

Apps Script scriptlets will only work if you return your html content by creating and evaluating a template rather than directly creating an output.


问:
Add additional columns to Spark dataframe
I parse Spark dataframe using file paths but now I would like to add paths to the resulting dataframe along with time as a separate column too. Here is a current solution (pathToDF is a helper method):

```<code>val paths = pathsDF
  .orderBy($"time")
  .select($"path")
  .as[String]
  .collect()

if(paths.nonEmpty) {
  paths
    .grouped(groupsNum.getOrElse(paths.length))
    .map(_.map(pathToDF).reduceLeft(_ union _))
} else {
  Seq.empty[DataFrame]
}
</code>```

I am trying to do something like this but I am not sure how to add time column too using withColumn:

```<code>    val orderedPaths = pathsDF
      .orderBy($"time")
      .select($"path")
   //.select($"path", $"time") for both columns

    val paths = orderedPaths
      .as[String]
      .collect()

    if (paths.nonEmpty) {
      paths
        .grouped(groupsNum.getOrElse(paths.length))
        .map(group => group.map(pathToDataDF).reduceLeft(_ union _)
          .withColumn("path", orderedPaths("path")))
    //.withColumn("time", orderedPaths("time") something like this
    } else {
      Seq.empty[DataFrame]
    }
</code>```

What would be a better way to implement it?

Input DF:

```<code>time Long
path String
</code>```

Current result:

```<code>resultDF schema
field1 Int
field2 String
....
fieldN String
</code>```

Expected result:

```<code>resultDF schema
field1 Int
field2 String
....
path   String
time   Long
</code>```

答:
Please check below code.

1. Change grouped to par function for parallel data load.

2. Change

```<code>// Below code will add same path for multiple files content.
paths.grouped(groupsNum.getOrElse(paths.length))
     .map(group => group.map(pathToDataDF).reduceLeft(_ union _)
     .withColumn("path", orderedPaths("path")))

</code>```

to

```<code>// Below code will add same path for same file content.
paths
.grouped(groupsNum.getOrElse(paths.length))
.flatMap(group => {
    group.map(path => {
        pathToDataDF(path).withColumn("path", lit(path))
        }
    )
})
.reduceLeft(_ union _)

</code>```

For example I have used both par & grouped to show you.

Note Ignore some of method like pathToDataDF I have tried to replicate your methods.

```<code>scala> val orderedPaths = Seq(("/tmp/data/foldera/foldera.json","2020-05-29 01:30:00"),("/tmp/data/folderb/folderb.json","2020-05-29 02:00:00"),("/tmp/data/folderc/folderc.json","2020-05-29 03:00:00")).toDF("path","time")
orderedPaths: org.apache.spark.sql.DataFrame = [path: string, time: string]

scala> def pathToDataDF(path: String) = spark.read.format("json").load(path)
pathToDataDF: (path: String)org.apache.spark.sql.DataFrame

//Sample File content I have taken.

scala> "cat /tmp/data/foldera/foldera.json".!
{"name":"Srinivas","age":29}

scala> "cat /tmp/data/folderb/folderb.json".!
{"name":"Ravi","age":20}

scala> "cat /tmp/data/folderc/folderc.json".!
{"name":"Raju","age":25}
</code>```

Using par

```<code>scala> val paths = orderedPaths.orderBy($"time").select($"path").as[String].collect
paths: Array[String] = Array(/tmp/data/foldera/foldera.json, /tmp/data/folderb/folderb.json, /tmp/data/folderc/folderc.json)

scala> val parDF = paths match {
        case p if !p.isEmpty => {
            p.par
            .map(path => {
                pathToDataDF(path)
                .withColumn("path",lit(path))
            }).reduceLeft(_ union _)
        }
        case _ => spark.emptyDataFrame
    }
parDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 1 more field]

scala> parDF.show(false)
+---+--------+------------------------------+
|age|name    |path                          |
+---+--------+------------------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|
|20 |Ravi    |/tmp/data/folderb/folderb.json|
|25 |Raju    |/tmp/data/folderc/folderc.json|
+---+--------+------------------------------+

// With time column.

scala> val paths = orderedPaths.orderBy($"time").select($"path",$"time").as[(String,String)].collect
paths: Array[(String, String)] = Array((/tmp/data/foldera/foldera.json,2020-05-29 01:30:00), (/tmp/data/folderb/folderb.json,2020-05-29 02:00:00), (/tmp/data/folderc/folderc.json,2020-05-29 03:00:00))

scala> val parDF = paths match {
            case p if !p.isEmpty => {
                p.par
                .map(path => {
                    pathToDataDF(path._1)
                    .withColumn("path",lit(path._1))
                    .withColumn("time",lit(path._2))
                }).reduceLeft(_ union _)
            }
            case _ => spark.emptyDataFrame
        }

parDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 2 more fields]

scala> parDF.show(false)
+---+--------+------------------------------+-------------------+
|age|name    |path                          |time               |
+---+--------+------------------------------+-------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|2020-05-29 01:30:00|
|20 |Ravi    |/tmp/data/folderb/folderb.json|2020-05-29 02:00:00|
|25 |Raju    |/tmp/data/folderc/folderc.json|2020-05-29 03:00:00|
+---+--------+------------------------------+-------------------+

</code>```

Using grouped

```<code>scala> val paths = orderedPaths.orderBy($"time").select($"path").as[String].collect
paths: Array[String] = Array(/tmp/data/foldera/foldera.json, /tmp/data/folderb/folderb.json, /tmp/data/folderc/folderc.json)

scala> val groupedDF = paths match {
            case p if !p.isEmpty => {
                paths
                .grouped(groupsNum.getOrElse(paths.length))
                .flatMap(group => {
                    group
                    .map(path => {
                        pathToDataDF(path)
                        .withColumn("path", lit(path))
                    })
                }).reduceLeft(_ union _)
            }
            case _ => spark.emptyDataFrame
        }

groupedDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 1 more field]

scala> groupedDF.show(false)

+---+--------+------------------------------+
|age|name    |path                          |
+---+--------+------------------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|
|20 |Ravi    |/tmp/data/folderb/folderb.json|
|25 |Raju    |/tmp/data/folderc/folderc.json|
+---+--------+------------------------------+

// with time column.

scala> val paths = orderedPaths.orderBy($"time").select($"path",$"time").as[(String,String)].collect
paths: Array[(String, String)] = Array((/tmp/data/foldera/foldera.json,2020-05-29 01:30:00), (/tmp/data/folderb/folderb.json,2020-05-29 02:00:00), (/tmp/data/folderc/folderc.json,2020-05-29 03:00:00))

scala> val groupedDF = paths match {
            case p if !p.isEmpty => {
                paths
                .grouped(groupsNum.getOrElse(paths.length))
                .flatMap(group => {
                    group
                    .map(path => {
                        pathToDataDF(path._1)
                        .withColumn("path",lit(path._1))
                        .withColumn("time",lit(path._2))
                    })
                }).reduceLeft(_ union _)
            }
            case _ => spark.emptyDataFrame
        }

groupedDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 2 more fields]

scala> groupedDF.show(false)
+---+--------+------------------------------+-------------------+
|age|name    |path                          |time               |
+---+--------+------------------------------+-------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|2020-05-29 01:30:00|
|20 |Ravi    |/tmp/data/folderb/folderb.json|2020-05-29 02:00:00|
|25 |Raju    |/tmp/data/folderc/folderc.json|2020-05-29 03:00:00|
+---+--------+------------------------------+-------------------+

</code>```

Body:
I parse Spark dataframe using file paths but now I would like to add paths to the resulting dataframe along with time as a separate column too. Here is a current solution (pathToDF is a helper method):

val paths = pathsDF
  .orderBy($"time")
  .select($"path")
  .as[String]
  .collect()

if(paths.nonEmpty) {
  paths
    .grouped(groupsNum.getOrElse(paths.length))
    .map(_.map(pathToDF).reduceLeft(_ union _))
} else {
  Seq.empty[DataFrame]
}

I am trying to do something like this but I am not sure how to add time column too using withColumn:

    val orderedPaths = pathsDF
      .orderBy($"time")
      .select($"path")
   //.select($"path", $"time") for both columns

    val paths = orderedPaths
      .as[String]
      .collect()

    if (paths.nonEmpty) {
      paths
        .grouped(groupsNum.getOrElse(paths.length))
        .map(group => group.map(pathToDataDF).reduceLeft(_ union _)
          .withColumn("path", orderedPaths("path")))
    //.withColumn("time", orderedPaths("time") something like this
    } else {
      Seq.empty[DataFrame]
    }

What would be a better way to implement it?

Input DF:

time Long
path String

Current result:

resultDF schema
field1 Int
field2 String
....
fieldN String

Expected result:

resultDF schema
field1 Int
field2 String
....
path   String
time   Long

Body:
Please check below code.

1. Change grouped to par function for parallel data load.

2. Change

// Below code will add same path for multiple files content.
paths.grouped(groupsNum.getOrElse(paths.length))
     .map(group => group.map(pathToDataDF).reduceLeft(_ union _)
     .withColumn("path", orderedPaths("path")))

to

// Below code will add same path for same file content.
paths
.grouped(groupsNum.getOrElse(paths.length))
.flatMap(group => {
    group.map(path => {
        pathToDataDF(path).withColumn("path", lit(path))
        }
    )
})
.reduceLeft(_ union _)

For example I have used both par & grouped to show you.

Note Ignore some of method like pathToDataDF I have tried to replicate your methods.

scala> val orderedPaths = Seq(("/tmp/data/foldera/foldera.json","2020-05-29 01:30:00"),("/tmp/data/folderb/folderb.json","2020-05-29 02:00:00"),("/tmp/data/folderc/folderc.json","2020-05-29 03:00:00")).toDF("path","time")
orderedPaths: org.apache.spark.sql.DataFrame = [path: string, time: string]

scala> def pathToDataDF(path: String) = spark.read.format("json").load(path)
pathToDataDF: (path: String)org.apache.spark.sql.DataFrame

//Sample File content I have taken.

scala> "cat /tmp/data/foldera/foldera.json".!
{"name":"Srinivas","age":29}

scala> "cat /tmp/data/folderb/folderb.json".!
{"name":"Ravi","age":20}

scala> "cat /tmp/data/folderc/folderc.json".!
{"name":"Raju","age":25}

Using par

scala> val paths = orderedPaths.orderBy($"time").select($"path").as[String].collect
paths: Array[String] = Array(/tmp/data/foldera/foldera.json, /tmp/data/folderb/folderb.json, /tmp/data/folderc/folderc.json)

scala> val parDF = paths match {
        case p if !p.isEmpty => {
            p.par
            .map(path => {
                pathToDataDF(path)
                .withColumn("path",lit(path))
            }).reduceLeft(_ union _)
        }
        case _ => spark.emptyDataFrame
    }
parDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 1 more field]

scala> parDF.show(false)
+---+--------+------------------------------+
|age|name    |path                          |
+---+--------+------------------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|
|20 |Ravi    |/tmp/data/folderb/folderb.json|
|25 |Raju    |/tmp/data/folderc/folderc.json|
+---+--------+------------------------------+

// With time column.

scala> val paths = orderedPaths.orderBy($"time").select($"path",$"time").as[(String,String)].collect
paths: Array[(String, String)] = Array((/tmp/data/foldera/foldera.json,2020-05-29 01:30:00), (/tmp/data/folderb/folderb.json,2020-05-29 02:00:00), (/tmp/data/folderc/folderc.json,2020-05-29 03:00:00))

scala> val parDF = paths match {
            case p if !p.isEmpty => {
                p.par
                .map(path => {
                    pathToDataDF(path._1)
                    .withColumn("path",lit(path._1))
                    .withColumn("time",lit(path._2))
                }).reduceLeft(_ union _)
            }
            case _ => spark.emptyDataFrame
        }

parDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 2 more fields]

scala> parDF.show(false)
+---+--------+------------------------------+-------------------+
|age|name    |path                          |time               |
+---+--------+------------------------------+-------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|2020-05-29 01:30:00|
|20 |Ravi    |/tmp/data/folderb/folderb.json|2020-05-29 02:00:00|
|25 |Raju    |/tmp/data/folderc/folderc.json|2020-05-29 03:00:00|
+---+--------+------------------------------+-------------------+

Using grouped

scala> val paths = orderedPaths.orderBy($"time").select($"path").as[String].collect
paths: Array[String] = Array(/tmp/data/foldera/foldera.json, /tmp/data/folderb/folderb.json, /tmp/data/folderc/folderc.json)

scala> val groupedDF = paths match {
            case p if !p.isEmpty => {
                paths
                .grouped(groupsNum.getOrElse(paths.length))
                .flatMap(group => {
                    group
                    .map(path => {
                        pathToDataDF(path)
                        .withColumn("path", lit(path))
                    })
                }).reduceLeft(_ union _)
            }
            case _ => spark.emptyDataFrame
        }

groupedDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 1 more field]

scala> groupedDF.show(false)

+---+--------+------------------------------+
|age|name    |path                          |
+---+--------+------------------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|
|20 |Ravi    |/tmp/data/folderb/folderb.json|
|25 |Raju    |/tmp/data/folderc/folderc.json|
+---+--------+------------------------------+

// with time column.

scala> val paths = orderedPaths.orderBy($"time").select($"path",$"time").as[(String,String)].collect
paths: Array[(String, String)] = Array((/tmp/data/foldera/foldera.json,2020-05-29 01:30:00), (/tmp/data/folderb/folderb.json,2020-05-29 02:00:00), (/tmp/data/folderc/folderc.json,2020-05-29 03:00:00))

scala> val groupedDF = paths match {
            case p if !p.isEmpty => {
                paths
                .grouped(groupsNum.getOrElse(paths.length))
                .flatMap(group => {
                    group
                    .map(path => {
                        pathToDataDF(path._1)
                        .withColumn("path",lit(path._1))
                        .withColumn("time",lit(path._2))
                    })
                }).reduceLeft(_ union _)
            }
            case _ => spark.emptyDataFrame
        }

groupedDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string ... 2 more fields]

scala> groupedDF.show(false)
+---+--------+------------------------------+-------------------+
|age|name    |path                          |time               |
+---+--------+------------------------------+-------------------+
|29 |Srinivas|/tmp/data/foldera/foldera.json|2020-05-29 01:30:00|
|20 |Ravi    |/tmp/data/folderb/folderb.json|2020-05-29 02:00:00|
|25 |Raju    |/tmp/data/folderc/folderc.json|2020-05-29 03:00:00|
+---+--------+------------------------------+-------------------+


问:
Why fgrep is acting weird?
I am trying to use grep to extract the matching words from file1 in file2 and directing to output file.

I have file1

```<code>Acetoanaerobium sticklandii
Acetobacter pasteurianus
</code>```

like >1000 species.

File2

```<code>>WP_013360383.1 ATP-dependent Clp protease ATP-binding subunit [Acetoanaerobium sticklandii]
>WP_013360396.1 ATP-dependent Clp protease ATP-binding subunit [Acetoanaerobium sticklandii]
>WP_003623694.1 multidrug efflux RND transporter permease subunit [Acetobacter pasteurianus]
>WP_003624003.1 superoxide dismutase [Acetobacter pasteurianus]
>WP_003624029.1 UDP-galactopyranose mutase [Acetobacter pasteurianus]
>WP_003624540.1 mannose-1-phosphate guanylyltransferase/mannose-6-phosphate isomerase [Acetobacter pasteurianus]
>WP_077905956.1 effector protein [Salmonella enterica]
>WP_077905962.1 type III secretion system YopJ family effector AvrA [Salmonella enterica]
>WP_005544680.1 3-deoxy-8-phosphooctulonate synthase [Aggregatibacter actinomycetemcomitans]
>WP_005545812.1 MFS transporter [Aggregatibacter actinomycetemcomitans]
>WP_005546163.1 UTP--glucose-1-phosphate uridylyltransferase GalU [Aggregatibacter actinomycetemcomitans]
</code>```

and so on..

when I am using the code

```<code>grep -f file1 file2 > output
</code>```

or

```<code>fgrep -f file1 file2 > output
</code>```

The resulting output is the list containing the last line of file1 and remaining input list is ignoring by grep. Even with -w option also the output is same.

Why the grep is behaving like this?
Is it problem with my shell?
I am using MacBook with Mojave OS version.

Please suggest me equivalent awk commands.

I tried

```<code>awk 'NR==FNR{a[$0];next}$NF in a{print}' file1 file2 > output
</code>```

but resulted empty file.

答:
1st solution: Generic and faster solution than my 2nd solution here. This will look for string from [ to ] in Input_file2 irrespective of field's hard-coding here.

```<code>awk '
{ gsub(/\r/,"") }
FNR==NR{
  array[$0]
  next
}
match($0,/\[[^]]*/){
  val=substr($0,RSTART+1,RLENGTH-1)
}
(val in array)
' file1 file2
</code>```

Explanation: Added detailed explanation for above.

```<code>awk '                                     ##Starting awk program from here.
{ gsub(/\r/,"") }
FNR==NR{                                  ##Checkiing condition FNR==NR which will be TRUE hen file1 is being read.
  array[$0]                               ##Creating array with index of current line.
  next                                    ##next will skip all statements from here.
}
match($0,/\[[^]]*/){                      ##Using match to match from [ to till ] in line.
  val=substr($0,RSTART+1,RLENGTH-1)       ##Creating val which has sub-string from RSTART  to RLENGH here.
}
(val in array)                            ##Checking condition if val is present in array then print that line.
' file1 file2                             ##Mentioning Input_file names here.
</code>```

2nd solution: Could you please try following, written and tested with shown samples. This is more generic solution since field number is NOT hard coded in solution but this code will work irrespective of field numbers here.

```<code>awk '{ gsub(/\r/,"") } FNR==NR{array[$0];next} {for(i in array){if(match($0,i)){print;next}}}' file1 file2
</code>```

Explanation: Adding detailed explanation for above.

```<code>awk '                    ##Starting awk program from here.
{ gsub(/\r/,"") }
FNR==NR{                 ##Checking condition FNR==NR if that's true then do following.
  array[$0]              ##Creating an array with index of current line.
  next                   ##next will skip further statements from here.
}
{
  for(i in array){       ##Looping through array here.
    if(match($0,i)){     ##Checking if current key is present  in current line then do following.
      print              ##Printing current line here.
      next               ##next will skip further statements from here.
    }
  }
}
'  file1 file2           ##Mentioning Input_file names here.
</code>```

Title: Why fgrep is acting weird?

Body:
I am trying to use grep to extract the matching words from file1 in file2 and directing to output file.

I have file1

Acetoanaerobium sticklandii
Acetobacter pasteurianus

like >1000 species.

File2

>WP_013360383.1 ATP-dependent Clp protease ATP-binding subunit [Acetoanaerobium sticklandii]
>WP_013360396.1 ATP-dependent Clp protease ATP-binding subunit [Acetoanaerobium sticklandii]
>WP_003623694.1 multidrug efflux RND transporter permease subunit [Acetobacter pasteurianus]
>WP_003624003.1 superoxide dismutase [Acetobacter pasteurianus]
>WP_003624029.1 UDP-galactopyranose mutase [Acetobacter pasteurianus]
>WP_003624540.1 mannose-1-phosphate guanylyltransferase/mannose-6-phosphate isomerase [Acetobacter pasteurianus]
>WP_077905956.1 effector protein [Salmonella enterica]
>WP_077905962.1 type III secretion system YopJ family effector AvrA [Salmonella enterica]
>WP_005544680.1 3-deoxy-8-phosphooctulonate synthase [Aggregatibacter actinomycetemcomitans]
>WP_005545812.1 MFS transporter [Aggregatibacter actinomycetemcomitans]
>WP_005546163.1 UTP--glucose-1-phosphate uridylyltransferase GalU [Aggregatibacter actinomycetemcomitans]

and so on..

when I am using the code

grep -f file1 file2 > output

or

fgrep -f file1 file2 > output

The resulting output is the list containing the last line of file1 and remaining input list is ignoring by grep. Even with -w option also the output is same.

Why the grep is behaving like this?
Is it problem with my shell?
I am using MacBook with Mojave OS version.

Please suggest me equivalent awk commands.

I tried

awk 'NR==FNR{a[$0];next}$NF in a{print}' file1 file2 > output

but resulted empty file.

Body:
1st solution: Generic and faster solution than my 2nd solution here. This will look for string from [ to ] in Input_file2 irrespective of field's hard-coding here.

awk '
{ gsub(/\r/,"") }
FNR==NR{
  array[$0]
  next
}
match($0,/\[[^]]*/){
  val=substr($0,RSTART+1,RLENGTH-1)
}
(val in array)
' file1 file2

Explanation: Added detailed explanation for above.

awk '                                     ##Starting awk program from here.
{ gsub(/\r/,"") }
FNR==NR{                                  ##Checkiing condition FNR==NR which will be TRUE hen file1 is being read.
  array[$0]                               ##Creating array with index of current line.
  next                                    ##next will skip all statements from here.
}
match($0,/\[[^]]*/){                      ##Using match to match from [ to till ] in line.
  val=substr($0,RSTART+1,RLENGTH-1)       ##Creating val which has sub-string from RSTART  to RLENGH here.
}
(val in array)                            ##Checking condition if val is present in array then print that line.
' file1 file2                             ##Mentioning Input_file names here.

2nd solution: Could you please try following, written and tested with shown samples. This is more generic solution since field number is NOT hard coded in solution but this code will work irrespective of field numbers here.

awk '{ gsub(/\r/,"") } FNR==NR{array[$0];next} {for(i in array){if(match($0,i)){print;next}}}' file1 file2

Explanation: Adding detailed explanation for above.

awk '                    ##Starting awk program from here.
{ gsub(/\r/,"") }
FNR==NR{                 ##Checking condition FNR==NR if that's true then do following.
  array[$0]              ##Creating an array with index of current line.
  next                   ##next will skip further statements from here.
}
{
  for(i in array){       ##Looping through array here.
    if(match($0,i)){     ##Checking if current key is present  in current line then do following.
      print              ##Printing current line here.
      next               ##next will skip further statements from here.
    }
  }
}
'  file1 file2           ##Mentioning Input_file names here.


问:
Selenium - Java - how to assert/verify all links on a page are working, get title and verify against expected titles
I am new to test automation and i am currently working on a personal project

I have this method in which it finds all the links for a section on the page, clicks on each link, irritates through each tab and then gets the title of each page

However, i want a way to verify the titles of these links against a list of expected titles

What would be the best approach to modify this in order to do this? would it be better to store in an array and then assert/verify each title separately?

I have tried a few ways to assert by changes return type to String and also to List but with no luck

```<code>public void linksAreWorkingDashBoardLeftPanal() throws Exception {

    List<WebElement> li_All = links_myAccountNav.findElements(By.tagName("a"));
    for(int i = 0; i < li_All.size(); i++){

        String clickOnLinkTab = Keys.chord(Keys.CONTROL, Keys.ENTER);
        links_myAccountNav.findElements(By.tagName("a")).get(i).sendKeys(clickOnLinkTab);
        Thread.sleep(5000);

    }

    //Opens all the tabs
    Set<String> getTitleinWindow = driver.getWindowHandles();
    Iterator<String> it = getTitleinWindow.iterator();

    while(it.hasNext())
    {

          driver.switchTo().window(it.next());
          System.out.println(driver.getTitle());
    }
</code>```

答:
Thanks! I took what i needed from your code and it worked perfectly. </p>

<p>this work and i added my own assertion </p>

```<code>    List<WebElement> li_All = links_myAccountNav.findElements(By.tagName("a"));
    for(int i = 0; i < li_All.size(); i++){

        String clickOnLinkTab = Keys.chord(Keys.CONTROL, Keys.ENTER);
        links_myAccountNav.findElements(By.tagName("a")).get(i).sendKeys(clickOnLinkTab);

        }//Opens all the tabs
        Set<String> getTitleinWindow = driver.getWindowHandles();
        Iterator<String> it = getTitleinWindow.iterator();

        // Get the expected titles in a list.
        // You have to initiate and add expected titles to this list, before running the while loop.

        List<String> expectedTitleList = new ArrayList<>();
        expectedTitleList.add("Page 1 title");
        expectedTitleList.add("Page 2 title");
        expectedTitleList.add("Page 3 title");
        expectedTitleList.add("Page 4 title");
        expectedTitleList.add("Page 5 title");
        expectedTitleList.add("Page 6 title");
        expectedTitleList.add("Page 7 title");

        List<String> actualTitleList = new ArrayList<>();
           while(it.hasNext())
         {
                driver.switchTo().window(it.next());
                actualTitleList.add(driver.getTitle());
         }

        //System.out.println(expectedTitleList);
        // System.out.println(actualTitleList);

    if(actualTitleList.equals(expectedTitleList)).....
</code>```

Body:
I am new to test automation and i am currently working on a personal project

I have this method in which it finds all the links for a section on the page, clicks on each link, irritates through each tab and then gets the title of each page

However, i want a way to verify the titles of these links against a list of expected titles

What would be the best approach to modify this in order to do this? would it be better to store in an array and then assert/verify each title separately?

I have tried a few ways to assert by changes return type to String and also to List but with no luck

public void linksAreWorkingDashBoardLeftPanal() throws Exception {

    List<WebElement> li_All = links_myAccountNav.findElements(By.tagName("a"));
    for(int i = 0; i < li_All.size(); i++){

        String clickOnLinkTab = Keys.chord(Keys.CONTROL, Keys.ENTER);
        links_myAccountNav.findElements(By.tagName("a")).get(i).sendKeys(clickOnLinkTab);
        Thread.sleep(5000);

    }

    //Opens all the tabs
    Set<String> getTitleinWindow = driver.getWindowHandles();
    Iterator<String> it = getTitleinWindow.iterator();

    while(it.hasNext())
    {

          driver.switchTo().window(it.next());
          System.out.println(driver.getTitle());
    }

Body:
Thanks! I took what i needed from your code and it worked perfectly.

this work and i added my own assertion

    List<WebElement> li_All = links_myAccountNav.findElements(By.tagName("a"));
    for(int i = 0; i < li_All.size(); i++){

        String clickOnLinkTab = Keys.chord(Keys.CONTROL, Keys.ENTER);
        links_myAccountNav.findElements(By.tagName("a")).get(i).sendKeys(clickOnLinkTab);

        }//Opens all the tabs
        Set<String> getTitleinWindow = driver.getWindowHandles();
        Iterator<String> it = getTitleinWindow.iterator();

        // Get the expected titles in a list.
        // You have to initiate and add expected titles to this list, before running the while loop.

        List<String> expectedTitleList = new ArrayList<>();
        expectedTitleList.add("Page 1 title");
        expectedTitleList.add("Page 2 title");
        expectedTitleList.add("Page 3 title");
        expectedTitleList.add("Page 4 title");
        expectedTitleList.add("Page 5 title");
        expectedTitleList.add("Page 6 title");
        expectedTitleList.add("Page 7 title");

        List<String> actualTitleList = new ArrayList<>();
           while(it.hasNext())
         {
                driver.switchTo().window(it.next());
                actualTitleList.add(driver.getTitle());
         }

        //System.out.println(expectedTitleList);
        // System.out.println(actualTitleList);

    if(actualTitleList.equals(expectedTitleList)).....


问:
Flutter passing list of strings in CupertinoPicker widget using loops
I was trying to pass a list inside CupertinoPicker using loops  but I couldn't figure it </p>

<p>this image contains the function I was trying to build  </p>

```<code> const List<String> currenciesList = [
          'AUD',
          'BRL',
          'CAD',
          'CNY',
          'EUR',
          'GBP',
          'HKD',
          'IDR',
          'ILS',
          'INR',
          'JPY',
          'MXN',
          'NOK',
        ];

    Container(
            height: 150.0,
            alignment: Alignment.center,
            padding: EdgeInsets.only(bottom: 30.0),
            color: Colors.lightBlue,
            child:CupertinoPicker(
                backgroundColor: Colors.lightBlue,
                itemExtent: 32.0,
                onSelectedItemChanged: (selectedIndex){
                  print(selectedIndex);
                }, children:[
              Text('USD',style: whiteColor ),
              Text('EUR' , style: whiteColor),
              Text('GDP', style:whiteColor),
            ]
            ),
          ),
</code>```

答:
As of Dart 2.3 you can use Collection For:

```<code>CupertinoPicker(
children:[
          for (String name in currenciesList) Text( name ,style: whiteColor ),
        ]
)
</code>```

Body:
I was trying to pass a list inside CupertinoPicker using loops  but I couldn't figure it

this image contains the function I was trying to build

 const List<String> currenciesList = [
          'AUD',
          'BRL',
          'CAD',
          'CNY',
          'EUR',
          'GBP',
          'HKD',
          'IDR',
          'ILS',
          'INR',
          'JPY',
          'MXN',
          'NOK',
        ];

    Container(
            height: 150.0,
            alignment: Alignment.center,
            padding: EdgeInsets.only(bottom: 30.0),
            color: Colors.lightBlue,
            child:CupertinoPicker(
                backgroundColor: Colors.lightBlue,
                itemExtent: 32.0,
                onSelectedItemChanged: (selectedIndex){
                  print(selectedIndex);
                }, children:[
              Text('USD',style: whiteColor ),
              Text('EUR' , style: whiteColor),
              Text('GDP', style:whiteColor),
            ]
            ),
          ),

Body:
As of Dart 2.3 you can use Collection For:

CupertinoPicker(
children:[
          for (String name in currenciesList) Text( name ,style: whiteColor ),
        ]
)


问:
Fast method to access random image pixels and at most once
I'm learning OpenCV (C++) and as a simple practice, I designed a simple effect which makes some of image pixels black or white. I want each pixel to be edited at most once; so I added address of all pixels to a vector. But it made my code very slow; specially for large images or high amounts of effect. Here is my code:

void effect1(Mat& img, float amount)    // 100 ≥ amount ≥ 0
{
    vector<uchar*> addresses;
    int channels = img.channels();
    uchar* lastAddress = img.ptr<uchar>(0) + img.total() * channels;
    for (uchar* i = img.ptr<uchar>(0); i < lastAddress; i += channels) addresses.push_back(i);   //Fast Enough
    size_t count = img.total() * amount / 100 / 2;
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 255;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 0;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
}
```

I think rearranging vector items after erasing an item is what makes my code slow (if I remove addresses.erase, code will run fast).

Is there any fast method to select each random item from a collection (or a number range) at most once?

Also: I'm pretty sure such effect already exists. Does anyone know the name of it?

答:
Also: I'm pretty sure such effect already exists. Does anyone know the name of it?

The effect you're describing is called salt and pepper noise. There is no direct implementation in OpenCV that I know of though.

I think rearranging vector items after erasing an item is what makes
  my code slow (if I remove addresses.erase, code will run fast).

Im not sure why you add your pixels to a vector in your code, it would make much more sense and also be much more performant to directly work on the Mat object and change the pixel value directly. You could use OpenCVs inbuild Mat.at() function to directly change the pixel values to either 0 or 255.

I would create a single loop which generates random indexes in the range of your image dimension and manipulate the image pixels directly. That way you are in O(n) for your noise addition. You could also just search for "OpenCV" and "salt and pepper noise", I am sure there already are a lot of really performant implementations.

Body:
I'm learning OpenCV (C++) and as a simple practice, I designed a simple effect which makes some of image pixels black or white. I want each pixel to be edited at most once; so I added address of all pixels to a vector. But it made my code very slow; specially for large images or high amounts of effect. Here is my code:

void effect1(Mat& img, float amount)    // 100 ≥ amount ≥ 0
{
    vector<uchar*> addresses;
    int channels = img.channels();
    uchar* lastAddress = img.ptr<uchar>(0) + img.total() * channels;
    for (uchar* i = img.ptr<uchar>(0); i < lastAddress; i += channels) addresses.push_back(i);   //Fast Enough
    size_t count = img.total() * amount / 100 / 2;
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 255;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 0;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
}

I think rearranging vector items after erasing an item is what makes my code slow (if I remove addresses.erase, code will run fast).

Is there any fast method to select each random item from a collection (or a number range) at most once?

Also: I'm pretty sure such effect already exists. Does anyone know the name of it?


问:
How to avoid application crashing when launching AlertDialog using AsyncTask() in ANDROID?
In an Android application, by clicking a button, in a fragment, I want to show an AlertDialog using AsynTask() method. I have put, in onPreExecute(), the function which called the AlertDialog. In doInBackground(), there is a task running, and in onPostExecute(), I dismiss the AlertDialog.
The crash occurs just when I click the button. And it refers to line code in the LoadingDialog class, which is dialog.show();. I have tried many suggestions given on the site, but, the issue occurs again.
Could anyone help me?

This is the LoadingDialog.java

```<code>
    public class LoadingDialog {

    private Activity activity;
    private AlertDialog dialog;

    LoadingDialog(Activity myActivity){
        activity = myActivity;
    }

    public void startLoadingDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);

        LayoutInflater inflater = activity.getLayoutInflater();
        builder.setView(inflater.inflate(R.layout.custom_dialog, null));
        builder.setCancelable(false);

        dialog = builder.create();
        dialog.show();
    }

    public void dismissDialog(){
        dialog.dismiss();
    }
    }
</code>```

This is my Fragment class

```<code>
public class MyFragment extends Fragment {

    View view ;
    private Button btn_;
    private Activity activity;
    private AlertDialog dialog;
    private LoadingDialog loadingDialog;

    public MyFragment(){

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        this.view = inflater.inflate(R.layout.fragment_, container, false);

        loadingDialog = new LoadingDialog(getActivity());

        btn_ = this.view.findViewById(R.id._button);
        eventListnerReinitialiser();
        return this.view;
    }

    public void eventListnerReinitialiser() {
        this.btn_.setOnClickListener(v -> {
             new ShowDialogAsyncTask().execute();
        });
    }

    public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
        int s = 0;
        @Override
        protected void onPreExecute() {
            loadingDialog.startLoadingDialog();
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0;i<1000000;i++)
                s = s + i;
            Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            loadingDialog.dismissDialog();
            super.onPostExecute(result);
        }
    }

}
</code>```

And I have this error log in my console of Android studio

```<code>
    E/WindowManager: android.view.WindowLeaked: Activity com.example.myproject.Menu2Activity has leaked window DecorView@96c506[] that was originally added here
        at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:338)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
        at android.app.Dialog.show(Dialog.java:322)
</code>```

答:
You are showing a toast in the doInBackground() of the AsyncTask, and this cannot be done. You can only update the Ui in the main thread.

Showing the toast in the doInBackground() which is running in a  background thread throws a exception and your fragment is forced to shutdown at that moment but the dialog is still open which caused the exception.

So try calling the Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ; in the onPostExecute of AsyncTask.

Here is how to do the AsyncTask part.

```<code>public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
        int s = 0;
        @Override
        protected void onPreExecute() {
            loadingDialog.startLoadingDialog();
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0;i<100_000_000;i++)
                s = s + i;

            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            Toast.makeText(MainActivity.this, "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
            loadingDialog.dismissDialog();

            super.onPostExecute(result);
        }
    }
</code>```

Body:
In an Android application, by clicking a button, in a fragment, I want to show an AlertDialog using AsynTask() method. I have put, in onPreExecute(), the function which called the AlertDialog. In doInBackground(), there is a task running, and in onPostExecute(), I dismiss the AlertDialog.
The crash occurs just when I click the button. And it refers to line code in the LoadingDialog class, which is dialog.show();. I have tried many suggestions given on the site, but, the issue occurs again.
Could anyone help me?

This is the LoadingDialog.java

    public class LoadingDialog {

    private Activity activity;
    private AlertDialog dialog;

    LoadingDialog(Activity myActivity){
        activity = myActivity;
    }

    public void startLoadingDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);

        LayoutInflater inflater = activity.getLayoutInflater();
        builder.setView(inflater.inflate(R.layout.custom_dialog, null));
        builder.setCancelable(false);

        dialog = builder.create();
        dialog.show();
    }

    public void dismissDialog(){
        dialog.dismiss();
    }
    }

This is my Fragment class

public class MyFragment extends Fragment {

    View view ;
    private Button btn_;
    private Activity activity;
    private AlertDialog dialog;
    private LoadingDialog loadingDialog;

    public MyFragment(){

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        this.view = inflater.inflate(R.layout.fragment_, container, false);

        loadingDialog = new LoadingDialog(getActivity());

        btn_ = this.view.findViewById(R.id._button);
        eventListnerReinitialiser();
        return this.view;
    }

    public void eventListnerReinitialiser() {
        this.btn_.setOnClickListener(v -> {
             new ShowDialogAsyncTask().execute();
        });
    }

    public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
        int s = 0;
        @Override
        protected void onPreExecute() {
            loadingDialog.startLoadingDialog();
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0;i<1000000;i++)
                s = s + i;
            Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            loadingDialog.dismissDialog();
            super.onPostExecute(result);
        }
    }

}

And I have this error log in my console of Android studio

    E/WindowManager: android.view.WindowLeaked: Activity com.example.myproject.Menu2Activity has leaked window DecorView@96c506[] that was originally added here
        at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:338)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
        at android.app.Dialog.show(Dialog.java:322)

Body:
You are showing a toast in the doInBackground() of the AsyncTask, and this cannot be done. You can only update the Ui in the main thread.

Showing the toast in the doInBackground() which is running in a  background thread throws a exception and your fragment is forced to shutdown at that moment but the dialog is still open which caused the exception.

So try calling the Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ; in the onPostExecute of AsyncTask.

Here is how to do the AsyncTask part.

public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
        int s = 0;
        @Override
        protected void onPreExecute() {
            loadingDialog.startLoadingDialog();
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0;i<100_000_000;i++)
                s = s + i;

            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            Toast.makeText(MainActivity.this, "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
            loadingDialog.dismissDialog();

            super.onPostExecute(result);
        }
    }