问:
reset selectizeInputs each time I modify a numericInput in RShiny
I'm learning shiny and working with a numericInput connected to many selectizeInputs.

if the numeric input equals to 1 or 2, I would like to create respectively 1 and 2  selectizeInputs and select the "i"th modality of a vector called "modalities" for each selectizeInput EDIT : and that choices = modalities[i] only (and not modalities)

if the numeric input equals to 3 or 4, I would like to create respectively 3 and 4  selectizeInputs which are connected with each other (with choices = modalities). In other words : if an item is selected in one of the selectizeinputs i would like that it disappears from the other selectizeinputs' choices.

In addition (and this is what I have trouble with) I would like to "reset" all the selected SelectizeInputs each time I modify the numericInput. I tried with the observeEvent below and I tried to use an isolate(input$ui_number) but I did not find any solution to my question because i don't understand how to do it... !

Thank you for your help !

```<code>      library(shiny)

      modalities <- LETTERS[1:10]

      ui = tabPanel("Change modalities",
                    numericInput("ui_number", label = "Number of modalities",
                                 min = 1, max = 4, value = 3),
                    uiOutput("renderui")
      )

      server = function(input, output, session) {

        # Generate modalities select lists
        output$renderui <- renderUI({
          output = tagList()
          for (i in seq_len(input$ui_number)) {
            output[[i]] = selectizeInput(paste0("ui_mod_choose", i),
                                         label = paste0("Modality ", i),
                                         choices = modalities, multiple = TRUE)
          }
          return(output)
        })

        # if input$ui_number is modified to 3 or 4 : set selected to NULL ##### NOT WORKING
        observeEvent({input$ui_number},
                     {
                       n <- input$ui_number
                       if(n%in%c(3,4)){
                         for (i in seq_len(n)) {
                           updateSelectizeInput(session, paste0("ui_mod_choose",i),selected=NULL)
                         }
                       }

                     }

        )

        observe({

          n <- input$ui_number

          if(n%in%c(1,2)){ #if n=1 or 2 =>  Select the "i"th modality for each selectizeInput
            for (i in seq_len(n)) {
              updateSelectizeInput(session, paste0("ui_mod_choose",i),
                                   choices = modalities[i],
                                   selected = modalities[i]
              )
            }

          } else{   # if n=3 or 4 => Remove selected modalities from other select lists
            for (i in seq_len(n)) {
              vecteur <- unlist(lapply((1:n)[-i], function(i)
                input[[paste0("ui_mod_choose",i)]]))
              updateSelectizeInput(session, paste0("ui_mod_choose",i),
                                   choices = setdiff(modalities, vecteur),
                                   selected = input[[paste0("ui_mod_choose",i)]])
            }

          }

        })

      }

      runApp(shinyApp(ui, server))
</code>```

This issue corresponds to the following of this one :

lapply function using a numericInput parameter around an observeEvent in RShiny

EDIT2 : new try thanks to @Aurèle 's tip.
The only problem which remains is the 1:100 in lapply which can take time to load (did not find a solution to add a reactive content such as 1:input&ui_number around a conditional panel)

```<code>      library(shiny)

      modalities <- LETTERS[1:10]

      make_conditional_selectizeInputs <- function() {
        do.call(
          div,
          lapply(1:100, function(i)
            conditionalPanel(
              condition = sprintf("%d <= input.ui_number", i),
              selectizeInput(sprintf("ui_mod_choose%d", i),
                             label = sprintf("Modality %d", i),
                             choices = character(0), multiple = TRUE, selected = NULL)
            )
          )
        )
      }

      ui <- tabPanel(
        "Change modalities",
        uiOutput("rendernumeric"),
        #numericInput("ui_number", label = "Number of modalities", min = 1L, max = max, value = 1L),
        make_conditional_selectizeInputs()
      )

      server <- function(input, output, session) {

        max <- 4

        output$rendernumeric <- renderUI({
          numericInput("ui_number", label = "Number of modalities", min = 1L, max = max, value = 1L)
        })

        n <- reactive({
          n <- input$ui_number
          if (is.null(n) || is.na(n) || !n >= 0) 0 else n
        })

        # Reset all
        observeEvent(
          eventExpr = n(),
          handlerExpr = for (i in seq_len(max))
            updateSelectizeInput(
              session, sprintf("ui_mod_choose%d", i),
              choices = if (n() %in% 1:2 && i <= n()) modalities[i] else modalities,
              selected = if (n() %in% 1:2 && i <= n()) modalities[i] else NULL
            )
        )

        all_selected <- reactive({
          unlist(lapply(seq_len(max), function(i)
            input[[sprintf("ui_mod_choose%d", i)]]))
        })

        # Update available modalities
        observeEvent(
          eventExpr = all_selected(),
          handlerExpr = if (!n() %in% 1:2) for (i in seq_len(n())) {
            x <- input[[sprintf("ui_mod_choose%d", i)]]
            other_selected <- setdiff(all_selected(), x)
            updateSelectizeInput(session, sprintf("ui_mod_choose%d", i),
                                 choices = setdiff(modalities, other_selected),
                                 selected = x)
          }
        )

      }

      runApp(shinyApp(ui, server))
</code>```

答:
Basically, you just need one more line: selected = if (n %in% 1:2) modalities[i] else NULL whenever you regenerate your selectizeInputs.

```<code>library(shiny)

modalities <- LETTERS[1:10]

ui = tabPanel("Change modalities",
              numericInput("ui_number", label = "Number of modalities",
                           min = 1, max = 4, value = 3),
              uiOutput("renderui"))

server = function(input, output, session) {

  # Generate modalities select lists
  output$renderui <- renderUI({
    output = tagList()
    n <- input$ui_number
    n <- if (is.null(n) || is.na(n) || ! n >= 0) 0 else n
    for (i in seq_len(n)) {
      output[[i]] = selectizeInput(paste0("ui_mod_choose", i),
                                   label = paste0("Modality ", i),
                                   choices = if (n %in% 1:2) modalities[i] else modalities,
                                   multiple = TRUE,
                                   # Add this
                                   selected = if (n %in% 1:2) modalities[i] else NULL)
    }
    output
  })

  # Remove selected modalities from other select lists
  observe({
    n <- isolate(input$ui_number)
    if (!n %in% 1:2) for (i in seq_len(n)) {
      vecteur <- unlist(lapply((1:n)[-i], function(i)
        input[[paste0("ui_mod_choose",i)]]))
      updateSelectizeInput(session, paste0("ui_mod_choose",i),
                           choices = setdiff(modalities, vecteur),
                           selected = input[[paste0("ui_mod_choose",i)]])
    }
  })

}

runApp(shinyApp(ui, server))
</code>```

Body:
I'm learning shiny and working with a numericInput connected to many selectizeInputs.

if the numeric input equals to 1 or 2, I would like to create respectively 1 and 2  selectizeInputs and select the "i"th modality of a vector called "modalities" for each selectizeInput EDIT : and that choices = modalities[i] only (and not modalities)

if the numeric input equals to 3 or 4, I would like to create respectively 3 and 4  selectizeInputs which are connected with each other (with choices = modalities). In other words : if an item is selected in one of the selectizeinputs i would like that it disappears from the other selectizeinputs' choices.

In addition (and this is what I have trouble with) I would like to "reset" all the selected SelectizeInputs each time I modify the numericInput. I tried with the observeEvent below and I tried to use an isolate(input$ui_number) but I did not find any solution to my question because i don't understand how to do it... !

Thank you for your help !

      library(shiny)

      modalities <- LETTERS[1:10]

      ui = tabPanel("Change modalities",
                    numericInput("ui_number", label = "Number of modalities",
                                 min = 1, max = 4, value = 3),
                    uiOutput("renderui")
      )

      server = function(input, output, session) {

        # Generate modalities select lists
        output$renderui <- renderUI({
          output = tagList()
          for (i in seq_len(input$ui_number)) {
            output[[i]] = selectizeInput(paste0("ui_mod_choose", i),
                                         label = paste0("Modality ", i),
                                         choices = modalities, multiple = TRUE)
          }
          return(output)
        })

        # if input$ui_number is modified to 3 or 4 : set selected to NULL ##### NOT WORKING
        observeEvent({input$ui_number},
                     {
                       n <- input$ui_number
                       if(n%in%c(3,4)){
                         for (i in seq_len(n)) {
                           updateSelectizeInput(session, paste0("ui_mod_choose",i),selected=NULL)
                         }
                       }

                     }

        )

        observe({

          n <- input$ui_number

          if(n%in%c(1,2)){ #if n=1 or 2 =>  Select the "i"th modality for each selectizeInput
            for (i in seq_len(n)) {
              updateSelectizeInput(session, paste0("ui_mod_choose",i),
                                   choices = modalities[i],
                                   selected = modalities[i]
              )
            }

          } else{   # if n=3 or 4 => Remove selected modalities from other select lists
            for (i in seq_len(n)) {
              vecteur <- unlist(lapply((1:n)[-i], function(i)
                input[[paste0("ui_mod_choose",i)]]))
              updateSelectizeInput(session, paste0("ui_mod_choose",i),
                                   choices = setdiff(modalities, vecteur),
                                   selected = input[[paste0("ui_mod_choose",i)]])
            }

          }

        })

      }

      runApp(shinyApp(ui, server))

This issue corresponds to the following of this one :

lapply function using a numericInput parameter around an observeEvent in RShiny

EDIT2 : new try thanks to @Aurèle 's tip.
The only problem which remains is the 1:100 in lapply which can take time to load (did not find a solution to add a reactive content such as 1:input&ui_number around a conditional panel)

      library(shiny)

      modalities <- LETTERS[1:10]

      make_conditional_selectizeInputs <- function() {
        do.call(
          div,
          lapply(1:100, function(i)
            conditionalPanel(
              condition = sprintf("%d <= input.ui_number", i),
              selectizeInput(sprintf("ui_mod_choose%d", i),
                             label = sprintf("Modality %d", i),
                             choices = character(0), multiple = TRUE, selected = NULL)
            )
          )
        )
      }

      ui <- tabPanel(
        "Change modalities",
        uiOutput("rendernumeric"),
        #numericInput("ui_number", label = "Number of modalities", min = 1L, max = max, value = 1L),
        make_conditional_selectizeInputs()
      )

      server <- function(input, output, session) {

        max <- 4

        output$rendernumeric <- renderUI({
          numericInput("ui_number", label = "Number of modalities", min = 1L, max = max, value = 1L)
        })

        n <- reactive({
          n <- input$ui_number
          if (is.null(n) || is.na(n) || !n >= 0) 0 else n
        })

        # Reset all
        observeEvent(
          eventExpr = n(),
          handlerExpr = for (i in seq_len(max))
            updateSelectizeInput(
              session, sprintf("ui_mod_choose%d", i),
              choices = if (n() %in% 1:2 && i <= n()) modalities[i] else modalities,
              selected = if (n() %in% 1:2 && i <= n()) modalities[i] else NULL
            )
        )

        all_selected <- reactive({
          unlist(lapply(seq_len(max), function(i)
            input[[sprintf("ui_mod_choose%d", i)]]))
        })

        # Update available modalities
        observeEvent(
          eventExpr = all_selected(),
          handlerExpr = if (!n() %in% 1:2) for (i in seq_len(n())) {
            x <- input[[sprintf("ui_mod_choose%d", i)]]
            other_selected <- setdiff(all_selected(), x)
            updateSelectizeInput(session, sprintf("ui_mod_choose%d", i),
                                 choices = setdiff(modalities, other_selected),
                                 selected = x)
          }
        )

      }

      runApp(shinyApp(ui, server))

Body:
Basically, you just need one more line: selected = if (n %in% 1:2) modalities[i] else NULL whenever you regenerate your selectizeInputs.

library(shiny)

modalities <- LETTERS[1:10]

ui = tabPanel("Change modalities",
              numericInput("ui_number", label = "Number of modalities",
                           min = 1, max = 4, value = 3),
              uiOutput("renderui"))

server = function(input, output, session) {

  # Generate modalities select lists
  output$renderui <- renderUI({
    output = tagList()
    n <- input$ui_number
    n <- if (is.null(n) || is.na(n) || ! n >= 0) 0 else n
    for (i in seq_len(n)) {
      output[[i]] = selectizeInput(paste0("ui_mod_choose", i),
                                   label = paste0("Modality ", i),
                                   choices = if (n %in% 1:2) modalities[i] else modalities,
                                   multiple = TRUE,
                                   # Add this
                                   selected = if (n %in% 1:2) modalities[i] else NULL)
    }
    output
  })

  # Remove selected modalities from other select lists
  observe({
    n <- isolate(input$ui_number)
    if (!n %in% 1:2) for (i in seq_len(n)) {
      vecteur <- unlist(lapply((1:n)[-i], function(i)
        input[[paste0("ui_mod_choose",i)]]))
      updateSelectizeInput(session, paste0("ui_mod_choose",i),
                           choices = setdiff(modalities, vecteur),
                           selected = input[[paste0("ui_mod_choose",i)]])
    }
  })

}

runApp(shinyApp(ui, server))


来源: stackexchange

问:
Woocommerce Additional Message on Product Variation
I have a Wordpress website build with Woocommcerce. I want to add some extra fields for users to be able to personalize their products ( some text inputs for them to write whatever  they want). I thinks this needs to be done with custom attributes but I'm not sure.

I have tried this to add an extra attribute type:

```<code>add_filter("product_attributes_type_selector" , function( $array ){
    $array["textfield"] = __( 'Textfield', 'woocommerce' );
    return $array ;
});
</code>```

I have no idea where to go on from this or if this is the right approach.

IMPORTANT NOTE: I don't want to use any plugins, so don't recommend any please

答:
Do it using a custom function hooked in woocommerce_before_add_to_cart_button action hook, that will add a custom input text field before quantities field and add to cart button on variable products only:

```<code>// Adding a custom input text field before quantities field and add to cart button on variable products only
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_fields' , 10, 0 );
function custom_product_fields() {
    global $product;

    if( ! $product->is_type( 'variable' ) ) return; // Only for variable products

    echo '<div class="product-custom-fields">
        <label class="my-custom-field1" for="custom_textfield1">'.__( 'Label text: ', 'woocommerce' ).'<br>
            <input type="text" name="custom_textfield1" class="input-text" placeholder="'.__( 'Enter a text', 'woocommerce' ).'" value="">
        </label>
    </div>
    <br clear="all">';
}
</code>```

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works… so you will get something like:

You will use instead woocommerce_after_add_to_cart_button action hook, if you want to display this custom field under add to cart button,

But you should need to save this custom field in cart object when added to cart and to display it in cart and checkout pages too.

ContentLicense: CC BY-SA 4.0

Body:
I have a Wordpress website build with Woocommcerce. I want to add some extra fields for users to be able to personalize their products ( some text inputs for them to write whatever  they want). I thinks this needs to be done with custom attributes but I'm not sure.

I have tried this to add an extra attribute type:

add_filter("product_attributes_type_selector" , function( $array ){
    $array["textfield"] = __( 'Textfield', 'woocommerce' );
    return $array ;
});

I have no idea where to go on from this or if this is the right approach.

IMPORTANT NOTE: I don't want to use any plugins, so don't recommend any please

Body:
Do it using a custom function hooked in woocommerce_before_add_to_cart_button action hook, that will add a custom input text field before quantities field and add to cart button on variable products only:

// Adding a custom input text field before quantities field and add to cart button on variable products only
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_fields' , 10, 0 );
function custom_product_fields() {
    global $product;

    if( ! $product->is_type( 'variable' ) ) return; // Only for variable products

    echo '<div class="product-custom-fields">
        <label class="my-custom-field1" for="custom_textfield1">'.__( 'Label text: ', 'woocommerce' ).'<br>
            <input type="text" name="custom_textfield1" class="input-text" placeholder="'.__( 'Enter a text', 'woocommerce' ).'" value="">
        </label>
    </div>
    <br clear="all">';
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works… so you will get something like:

You will use instead woocommerce_after_add_to_cart_button action hook, if you want to display this custom field under add to cart button,

But you should need to save this custom field in cart object when added to cart and to display it in cart and checkout pages too.

ContentLicense: CC BY-SA 3.0


问:
Apostrophe CKEditor table cell merging issue
In apostrophe-rich-text widget when I paste a table (but it also happens when creating them manually) with merged cells it starts out fine:

But after a reload, colspans disappear:

Is there any way to fix it?

答:
Try whitelisting the colspan attribute in your project level apostrophe-rich-text-widgets index.js

```<code>module.exports = {
  sanitizeHtml: {
    allowedAttributes: {
      'td': ['colspan']
    }
  }
};
</code>```

Body:
Try whitelisting the colspan attribute in your project level apostrophe-rich-text-widgets index.js

module.exports = {
  sanitizeHtml: {
    allowedAttributes: {
      'td': ['colspan']
    }
  }
};


问:
Linked List in my Array not working
I am trying to create a program to store words in a Array. I have a hashFunction which computes a Integer value. This value is used to put the Word in a Node if that position in the array is null. If there is already a Cell there, it should create a new Cell with the word as its data type, and it should then point to the old Cell with all the other data. However this dosen't seem to be working - I have added a few words and although it adds the first word to the Cell the other words aren't being added. I'm not sure why this is happening - can someone show my why?</p>

```<code>public class test2{

    public static class Node<T>{
        public T data;
        public Node<T> next;

    public Node(T data, Node<T> next)
    {
       this.data = data;
       this.next = next;
    }
 }

    static Node[] array = new Node[10];

    public static void add(String word){
        int position = hashFunction(word);
        if(array[position] == null){
            array[position] = new Node(word, null);
        }else{
            new Node(word, array[position]);
        }
    }

    public static int hashFunction(String a){
        int sum = 1;
        for(int i = 0; i<a.length(); i++){
            char b = a.charAt(i);
            int value = (int) b;
            sum *= value;
        }
     return sum % array.length;
 }

 public static void main(String[] args) {
     add("abc");
     add("acb");
     add("bca");
     add("bac");
     add("cba");
     System.out.println(array[4].next);
 }
}
</code>```

答:
You're adding the word as a new node in your linked list, but you're never storing a reference to the new node. When you add a node at the beginning of a linked list, you have to store the new node as the new head of the list.

In your case, you could accomplish that with the following:

```<code>public static void add(String word){
    int position = hashFunction(word);
    if(array[position] == null){
        array[position] = new Node(word, null);
    }else{
        Node newHead = new Node(word, array[position]);
        array[position] = newHead;
    }
}
</code>```

Now your linked list will have all of the words you're expecting. You could also iterate over the linked list in array[position] and add the new node at the end of the list if that's more appropriate for your use case.

Title: Linked List in my Array not working

Body:
I am trying to create a program to store words in a Array. I have a hashFunction which computes a Integer value. This value is used to put the Word in a Node if that position in the array is null. If there is already a Cell there, it should create a new Cell with the word as its data type, and it should then point to the old Cell with all the other data. However this dosen't seem to be working - I have added a few words and although it adds the first word to the Cell the other words aren't being added. I'm not sure why this is happening - can someone show my why?

public class test2{

    public static class Node<T>{
        public T data;
        public Node<T> next;

    public Node(T data, Node<T> next)
    {
       this.data = data;
       this.next = next;
    }
 }

    static Node[] array = new Node[10];

    public static void add(String word){
        int position = hashFunction(word);
        if(array[position] == null){
            array[position] = new Node(word, null);
        }else{
            new Node(word, array[position]);
        }
    }

    public static int hashFunction(String a){
        int sum = 1;
        for(int i = 0; i<a.length(); i++){
            char b = a.charAt(i);
            int value = (int) b;
            sum *= value;
        }
     return sum % array.length;
 }

 public static void main(String[] args) {
     add("abc");
     add("acb");
     add("bca");
     add("bac");
     add("cba");
     System.out.println(array[4].next);
 }
}

Body:
You're adding the word as a new node in your linked list, but you're never storing a reference to the new node. When you add a node at the beginning of a linked list, you have to store the new node as the new head of the list.

In your case, you could accomplish that with the following:

public static void add(String word){
    int position = hashFunction(word);
    if(array[position] == null){
        array[position] = new Node(word, null);
    }else{
        Node newHead = new Node(word, array[position]);
        array[position] = newHead;
    }
}

Now your linked list will have all of the words you're expecting. You could also iterate over the linked list in array[position] and add the new node at the end of the list if that's more appropriate for your use case.


问:
Extra information for each word in richtextbox- Link between richtextbox and sql table
I have a richtextbox that its text is a concatenation of some words from specific table. (table columns are 'word','translate' and 'id')

I need that when a user hover on each word, the related translate is showed in word's tooltip.
(something like google translate but in windows form application.)

Can somebody point me towards a solution?

答:
This will do the trick...</p>

```<code>private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
     // whitespace definition
     char[] whitespace = new char[] { ' ', '\r', '\n', '\t' };

     int charPosition = this.richTextBox1.GetCharIndexFromPosition(e.Location);

     string fullText = this.richTextBox1.Text;

     // if we are on whitespace, exit
     if (whitespace.Contains(fullText[charPosition]))
     {
         return;
     }

     // find a whitespace towards the start of the text
     int firstWhiteSpace = charPosition;
     while (firstWhiteSpace > 0
         && firstWhiteSpace < fullText.Length
         && !whitespace.Contains(fullText[firstWhiteSpace]))
     {
         firstWhiteSpace--;
     }
     if (firstWhiteSpace!=0)
         firstWhiteSpace++;
     // find the next whitespace
     int lastWhiteSpace = fullText.IndexOfAny(whitespace, charPosition);
     if (lastWhiteSpace == -1)
         lastWhiteSpace = fullText.Length;

     // substring the word out of the flat text
     string word = fullText.Substring(
         firstWhiteSpace,
         lastWhiteSpace - firstWhiteSpace);

     // show the result
     label1.Text = String.Format("pos:{0} fsp:{1}, lsp:{2}, len:{3}, word:{4}",
         charPosition,
         firstWhiteSpace,
         lastWhiteSpace,
         fullText.Length, word);

 }
</code>```

ContentLicense: CC BY-SA 2.5

Body:
This will do the trick...

private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
     // whitespace definition
     char[] whitespace = new char[] { ' ', '\r', '\n', '\t' };

     int charPosition = this.richTextBox1.GetCharIndexFromPosition(e.Location);

     string fullText = this.richTextBox1.Text;

     // if we are on whitespace, exit
     if (whitespace.Contains(fullText[charPosition]))
     {
         return;
     }

     // find a whitespace towards the start of the text
     int firstWhiteSpace = charPosition;
     while (firstWhiteSpace > 0
         && firstWhiteSpace < fullText.Length
         && !whitespace.Contains(fullText[firstWhiteSpace]))
     {
         firstWhiteSpace--;
     }
     if (firstWhiteSpace!=0)
         firstWhiteSpace++;
     // find the next whitespace
     int lastWhiteSpace = fullText.IndexOfAny(whitespace, charPosition);
     if (lastWhiteSpace == -1)
         lastWhiteSpace = fullText.Length;

     // substring the word out of the flat text
     string word = fullText.Substring(
         firstWhiteSpace,
         lastWhiteSpace - firstWhiteSpace);

     // show the result
     label1.Text = String.Format("pos:{0} fsp:{1}, lsp:{2}, len:{3}, word:{4}",
         charPosition,
         firstWhiteSpace,
         lastWhiteSpace,
         fullText.Length, word);

 }


问:
Django model method to count method flag of foreignkeys
I have two models Assessment and Answer with a OnetoMany relationship.

models.py

```<code>class Assessment(models.Model):
    name = models.CharField(max_length=255, blank=False)
    def __str__(self):
        return "{}".format(self.name)

    def _all_answers_completed(self):
         pass
         #some how get all related answers
         #then see if "completed" = true
         #if all = true then return true
         #if any = false then return false
    completed = property(_all_answers_completed)

class Answer(models.Model):
    assessment = models.ForeignKey(Assessment, null=True, blank=True, on_delete=models.CASCADE)
    score_risk = models.IntegerField(default=0)
    score_impact = models.IntegerField(default=0)
    score_occurrance = models.IntegerField(default=0)
    def __str__(self):
        return "Answer to Question:{} for Assessment {}".format(self.question, self.assessment)

    def _is_answered(self):
        if self.score_risk > 0 and self.score_impact >0  and self.score_occurrance > 0:
            return True
        else:
            return False
    completed = property(_is_answered)
</code>```

I want to set the assessment method completed based on the related answers property answer.completed

I just don't know how to do this or do I have to do this in a view via looping through a queryset.

答:
You can get all the "answers" related to the current "Assessment" object and then simply loop through them to find if all answers are completed or not.

Your code should look something similar to this (untested):

```<code>def _all_answers_completed(self):
    answers = self.answer_set.all()
    for answer in answers:
        if not answer.completed:
            return False
    return True
</code>```

Here self.answer_set will get all the Answer objects who have a foreign key of the current Assesment object (i.e. self). You can read more about it here and here

Body:
I have two models Assessment and Answer with a OnetoMany relationship.

models.py

class Assessment(models.Model):
    name = models.CharField(max_length=255, blank=False)
    def __str__(self):
        return "{}".format(self.name)

    def _all_answers_completed(self):
         pass
         #some how get all related answers
         #then see if "completed" = true
         #if all = true then return true
         #if any = false then return false
    completed = property(_all_answers_completed)

class Answer(models.Model):
    assessment = models.ForeignKey(Assessment, null=True, blank=True, on_delete=models.CASCADE)
    score_risk = models.IntegerField(default=0)
    score_impact = models.IntegerField(default=0)
    score_occurrance = models.IntegerField(default=0)
    def __str__(self):
        return "Answer to Question:{} for Assessment {}".format(self.question, self.assessment)

    def _is_answered(self):
        if self.score_risk > 0 and self.score_impact >0  and self.score_occurrance > 0:
            return True
        else:
            return False
    completed = property(_is_answered)

I want to set the assessment method completed based on the related answers property answer.completed

I just don't know how to do this or do I have to do this in a view via looping through a queryset.

Body:
You can get all the "answers" related to the current "Assessment" object and then simply loop through them to find if all answers are completed or not.

Your code should look something similar to this (untested):

def _all_answers_completed(self):
    answers = self.answer_set.all()
    for answer in answers:
        if not answer.completed:
            return False
    return True

Here self.answer_set will get all the Answer objects who have a foreign key of the current Assesment object (i.e. self). You can read more about it here and here


问:
Dynamically created elements all return the same index
I'm dynamically creating dropdowns in a table, and I'm trying to grab the index of the dropdown that triggered the event, like so:

```<code>$(".template").on('change', '.dataTypes', function () {
    var selectedDatatype = $(this).find(":selected").val();
    var ix = $(this).index(); // get this index

    $.ajax({
        type: "GET",
        url: "http://localhost...",
        contentType: "application/json; charset=utf-8",
        success: function (result) {
            populateListDropdown("gs", ix, result.Result);
        },
        error: function () { },
        timeout: 120000
    });
});
</code>```

This code, regardless of the dropdown I interact with always returns a 0 for the index and I'm not sure why.

HTML if it's helpful. The page has a single row loaded at startup, and additional are added via button click.

```<code><table class="tblColumns">
    <tr>
        <td>
            <div class="column">
                Select DataType :
                <select class="dataTypes"></select>
        </td>
    </tr>
</table>
</code>```

答:
index() method returns index based on its siblings. Your all dropdowns are in seperate td. So all have same index.

You are looking for tr index not select. Try

```<code>$(this).closest('tr').index();
</code>```

Body:
I'm dynamically creating dropdowns in a table, and I'm trying to grab the index of the dropdown that triggered the event, like so:

$(".template").on('change', '.dataTypes', function () {
    var selectedDatatype = $(this).find(":selected").val();
    var ix = $(this).index(); // get this index

    $.ajax({
        type: "GET",
        url: "http://localhost...",
        contentType: "application/json; charset=utf-8",
        success: function (result) {
            populateListDropdown("gs", ix, result.Result);
        },
        error: function () { },
        timeout: 120000
    });
});

This code, regardless of the dropdown I interact with always returns a 0 for the index and I'm not sure why.

HTML if it's helpful. The page has a single row loaded at startup, and additional are added via button click.

                Select DataType :
                <select class="dataTypes"></select>

Body:
index() method returns index based on its siblings. Your all dropdowns are in seperate td. So all have same index.

You are looking for tr index not select. Try

$(this).closest('tr').index();


问:
How to "flatten" or "collapse" a 2D Excel table into 1D?
I have a two dimensional table with countries and years in Excel. eg.

```<code>        1961        1962        1963        1964
USA      a           x            g           y
France   u           e            h           a
Germany  o           x            n           p
</code>```

I'd like to "flatten" it, such that I have Country in the first col, Year in the second col, and then value in the third col. eg.

```<code>Country      Year       Value
USA          1961       a
USA          1962       x
USA          1963       g
USA          1964       y
France       1961       u
              ...
</code>```

The example I present here is only a 3x4 matrix, but the real dataset i have is significantly larger (roughly 50x40 or so).

Any suggestions how I can do this using Excel?

答:
updated ReversePivotTable function so i can specify number of header columns and rows</p>

```<code>Sub ReversePivotTable()
'   Before running this, make sure you have a summary table with column headers.
'   The output table will have three columns.
    Dim SummaryTable As Range, OutputRange As Range
    Dim OutRow As Long
    Dim r As Long, c As Long

    Dim lngHeaderColumns As Long, lngHeaderRows As Long, lngHeaderLoop As Long

    On Error Resume Next
    Set SummaryTable = ActiveCell.CurrentRegion
    If SummaryTable.Count = 1 Or SummaryTable.Rows.Count < 3 Then
        MsgBox "Select a cell within the summary table.", vbCritical
        Exit Sub
    End If
    SummaryTable.Select

    Set OutputRange = Application.InputBox(prompt:="Select a cell for the 3-column output", Type:=8)
    lngHeaderColumns = Application.InputBox(prompt:="Header Columns")
    lngHeaderRows = Application.InputBox(prompt:="Header Rows")
'   Convert the range
    OutRow = 2
    Application.ScreenUpdating = False
    'OutputRange.Range("A1:D3") = Array("Column1", "Column2", "Column3", "Column4")
    For r = lngHeaderRows + 1 To SummaryTable.Rows.Count
        For c = lngHeaderColumns + 1 To SummaryTable.Columns.Count
            ' loop through all header columns and add to output
            For lngHeaderLoop = 1 To lngHeaderColumns
                OutputRange.Cells(OutRow, lngHeaderLoop) = SummaryTable.Cells(r, lngHeaderLoop)
            Next lngHeaderLoop
            ' loop through all header rows and add to output
            For lngHeaderLoop = 1 To lngHeaderRows
                OutputRange.Cells(OutRow, lngHeaderColumns + lngHeaderLoop) = SummaryTable.Cells(lngHeaderLoop, c)
            Next lngHeaderLoop

            OutputRange.Cells(OutRow, lngHeaderColumns + lngHeaderRows + 1) = SummaryTable.Cells(r, c)
            OutputRange.Cells(OutRow, lngHeaderColumns + lngHeaderRows + 1).NumberFormat = SummaryTable.Cells(r, c).NumberFormat
            OutRow = OutRow + 1
        Next c
    Next r
End Sub
</code>```

OwnerDisplayName: Mike

Body:
I have a two dimensional table with countries and years in Excel. eg.

        1961        1962        1963        1964
USA      a           x            g           y
France   u           e            h           a
Germany  o           x            n           p

I'd like to "flatten" it, such that I have Country in the first col, Year in the second col, and then value in the third col. eg.

Country      Year       Value
USA          1961       a
USA          1962       x
USA          1963       g
USA          1964       y
France       1961       u
              ...

The example I present here is only a 3x4 matrix, but the real dataset i have is significantly larger (roughly 50x40 or so).

Any suggestions how I can do this using Excel?

Body:
updated ReversePivotTable function so i can specify number of header columns and rows

Sub ReversePivotTable()
'   Before running this, make sure you have a summary table with column headers.
'   The output table will have three columns.
    Dim SummaryTable As Range, OutputRange As Range
    Dim OutRow As Long
    Dim r As Long, c As Long

    Dim lngHeaderColumns As Long, lngHeaderRows As Long, lngHeaderLoop As Long

    On Error Resume Next
    Set SummaryTable = ActiveCell.CurrentRegion
    If SummaryTable.Count = 1 Or SummaryTable.Rows.Count < 3 Then
        MsgBox "Select a cell within the summary table.", vbCritical
        Exit Sub
    End If
    SummaryTable.Select

    Set OutputRange = Application.InputBox(prompt:="Select a cell for the 3-column output", Type:=8)
    lngHeaderColumns = Application.InputBox(prompt:="Header Columns")
    lngHeaderRows = Application.InputBox(prompt:="Header Rows")
'   Convert the range
    OutRow = 2
    Application.ScreenUpdating = False
    'OutputRange.Range("A1:D3") = Array("Column1", "Column2", "Column3", "Column4")
    For r = lngHeaderRows + 1 To SummaryTable.Rows.Count
        For c = lngHeaderColumns + 1 To SummaryTable.Columns.Count
            ' loop through all header columns and add to output
            For lngHeaderLoop = 1 To lngHeaderColumns
                OutputRange.Cells(OutRow, lngHeaderLoop) = SummaryTable.Cells(r, lngHeaderLoop)
            Next lngHeaderLoop
            ' loop through all header rows and add to output
            For lngHeaderLoop = 1 To lngHeaderRows
                OutputRange.Cells(OutRow, lngHeaderColumns + lngHeaderLoop) = SummaryTable.Cells(lngHeaderLoop, c)
            Next lngHeaderLoop

            OutputRange.Cells(OutRow, lngHeaderColumns + lngHeaderRows + 1) = SummaryTable.Cells(r, c)
            OutputRange.Cells(OutRow, lngHeaderColumns + lngHeaderRows + 1).NumberFormat = SummaryTable.Cells(r, c).NumberFormat
            OutRow = OutRow + 1
        Next c
    Next r
End Sub


问:
How to operate on javascript function generator which is an object property
I would like to place js generator as an object property and operate on it from within other object properties. The code execution would be triggered via events. Below is short version of the code idea:

```<code>var obj = {
  property1: {
    generator: function* (){
      console.log("gen start");
      yield;
      console.log("gen part 1");
    },
    gener: function() {
      return obj.property1.generator();
    },
    addMonthsGrid: function() {
      console.log("genNext 1");
      obj.property1.gener().next();
    }
  },
  property2: {
    exec2: function() {
      console.log("intermediate stuff...");
      console.log("genNext 2");
      obj.property1.gener().next();
    }
  }
};
/* first event that should run first part of generator: */
  obj.property1.addMonthsGrid();
/* second event hat should run second part of generator: */
  obj.property2.exec2(); //here it starts from the beggining
</code>```

The problem is that the second call starts generator from the beggining (not continue it). I suppose that the problem might be in obj.property1.gener, which returns the generator, but I don't know how to make it works. I would be grateful for your help!.

答:
Yes, gener does create a new generator every time it is called.

```<code>const obj = {
  generatorFunction: function* (){
    console.log("gen start");
    yield;
    console.log("gen part 1");
  },
  generate: function() {
    this.generator = this.generatorFunction();
    return this.generator;
  },
  addMonthsGrid: function() {
    console.log("genNext 1");
    this.generator.next();
  }
};
</code>```

With this you can do

```<code>obj.generate();
obj.addMonthsGrid();
obj.generator.next();
</code>```

Body:
I would like to place js generator as an object property and operate on it from within other object properties. The code execution would be triggered via events. Below is short version of the code idea:

var obj = {
  property1: {
    generator: function* (){
      console.log("gen start");
      yield;
      console.log("gen part 1");
    },
    gener: function() {
      return obj.property1.generator();
    },
    addMonthsGrid: function() {
      console.log("genNext 1");
      obj.property1.gener().next();
    }
  },
  property2: {
    exec2: function() {
      console.log("intermediate stuff...");
      console.log("genNext 2");
      obj.property1.gener().next();
    }
  }
};
/* first event that should run first part of generator: */
  obj.property1.addMonthsGrid();
/* second event hat should run second part of generator: */
  obj.property2.exec2(); //here it starts from the beggining

The problem is that the second call starts generator from the beggining (not continue it). I suppose that the problem might be in obj.property1.gener, which returns the generator, but I don't know how to make it works. I would be grateful for your help!.

Body:
Yes, gener does create a new generator every time it is called.

const obj = {
  generatorFunction: function* (){
    console.log("gen start");
    yield;
    console.log("gen part 1");
  },
  generate: function() {
    this.generator = this.generatorFunction();
    return this.generator;
  },
  addMonthsGrid: function() {
    console.log("genNext 1");
    this.generator.next();
  }
};

With this you can do

obj.generate();
obj.addMonthsGrid();
obj.generator.next();


问:
Powershell - getting the scriptname of calling script in dot-sourced function
is there any way to get the scriptname of the calling script into a dot-sourced ps1 script?
This would be awsome for logging.

eg: script test1.ps1 is calling a function from dot-sourced log.ps1.

The String "test.ps1" is needed in log.ps1. Is this possible?
Thanks in advance

答:
I was trying to solve similar or maybe same problem - how to generate log file name based on script name. Solution from @SomeShinyObject is nice but when you have your logging script sourced from file, that is sourced from another file, then you have problem. I have arrived at following solution. In case anyone is interested.

```<code>$scriptFileName = Get-Item (Get-PSCallStack)[(Get-PSCallStack).length-1].ScriptName
$log = "$($scriptFileName.DirectoryName)\log\$($scriptFileName.Basename).log"
</code>```

It basically gets highest frame from the call stack by first getting stack depth using (Get-PSCallStack).length then it uses this value in obtaining the frame itself and gets ScriptName from there, which is uppermost script in calling hierarchy.

Body:
I was trying to solve similar or maybe same problem - how to generate log file name based on script name. Solution from @SomeShinyObject is nice but when you have your logging script sourced from file, that is sourced from another file, then you have problem. I have arrived at following solution. In case anyone is interested.

$scriptFileName = Get-Item (Get-PSCallStack)[(Get-PSCallStack).length-1].ScriptName
$log = "$($scriptFileName.DirectoryName)\log\$($scriptFileName.Basename).log"

It basically gets highest frame from the call stack by first getting stack depth using (Get-PSCallStack).length then it uses this value in obtaining the frame itself and gets ScriptName from there, which is uppermost script in calling hierarchy.


问:
missing ] after element list (JSON.parse using reviver )

Executing that:

```<code>function myFunction() {
  var hash = JSON.parse('{"a":"return num"}', function(k, v){ new Function('num', v)(123) });
}
</code>```

I want to get hashmap:
    {a=123}

However, Google Apps Script Says:

SyntaxError: missing ] after element list

I know below code works well, but I want that the value of JSON contains "return".

```<code>function myFunction() {
  var num = 123;
  var hash = JSON.parse('{"a": "num"}', function(k, v){return eval(v)});
}
</code>```

答:
The reviver function runs once for every item found in the input. In the case of this JSON string:

```<code>{"a":"return num"}
</code>```

it will run two times (!). First for the inner key-value pair "a":"return num" and then for the root object itself (key-value pair "": {"a":"return num"}).

You only want to do something when the key is "a", in all other cases you want to return the value unchanged.

var json = '{"a":"return num"}';
var revived = JSON.parse(json, function (k, v) {
    if (k === "a") {
        return (new Function('num', v))(123);
    } else {
        return v;
    }
});

console.log(revived);```
</div>
</div>
</p>

<p>Be careful, doing this is dangerous. <code>new Function</code> is effectively the same as <code>eval()</code>, so I suggest you think hard about better ways of doing what you want.</p>

<p>How about using a config object and a special syntax convention to replace certain values in the data with values from the config:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>var config = {
    num: 123
};

var json = '{"a":"{{num}}"}';
var revived = JSON.parse(json, function (k, v) {
    var match = typeof v === "string" && v.match(/^{{(\w+)}}$/);
    if (match && config.hasOwnProperty(match[1])) {
        return config[match[1]];
    } else {
        return v;
    }
});

console.log(revived);</code>```

Body:
Executing that:

function myFunction() {
  var hash = JSON.parse('{"a":"return num"}', function(k, v){ new Function('num', v)(123) });
}

I want to get hashmap:
    {a=123}

However, Google Apps Script Says:

SyntaxError: missing ] after element list

I know below code works well, but I want that the value of JSON contains "return".

function myFunction() {
  var num = 123;
  var hash = JSON.parse('{"a": "num"}', function(k, v){return eval(v)});
}

Body:
The reviver function runs once for every item found in the input. In the case of this JSON string:

{"a":"return num"}

it will run two times (!). First for the inner key-value pair "a":"return num" and then for the root object itself (key-value pair "": {"a":"return num"}).

You only want to do something when the key is "a", in all other cases you want to return the value unchanged.

var json = '{"a":"return num"}';
var revived = JSON.parse(json, function (k, v) {
    if (k === "a") {
        return (new Function('num', v))(123);
    } else {
        return v;
    }
});

console.log(revived);

Be careful, doing this is dangerous. new Function is effectively the same as eval(), so I suggest you think hard about better ways of doing what you want.

How about using a config object and a special syntax convention to replace certain values in the data with values from the config:

var config = {
    num: 123
};

var json = '{"a":"{{num}}"}';
var revived = JSON.parse(json, function (k, v) {
    var match = typeof v === "string" && v.match(/^{{(\w+)}}$/);
    if (match && config.hasOwnProperty(match[1])) {
        return config[match[1]];
    } else {
        return v;
    }
});

console.log(revived);


问:
How to get the assembly information of an imported UserControl through MEF, without instantiating UserControl?
Is it possible get the assembly information from an imported MEF Type, without instantiating a type? I need to know the assembly name and version of the Plugin control that contains the Type. Tried the following, but it just returns the System.ComponentModel.Composition.

```<code>foreach (Lazy<UserControl, IMetadata> content in contents)
{
    // get assembly information of the Plugin control for the imported function
    string definingAssembly = content.GetType().Assembly.GetName();
    Console.WriteLine(definingAssembly);
}
</code>```

To avoid maintenance issues if possible I want to avoid specifying this information in Metadata.

答:
This is a FAQ that pops up on the MEF forum every now and then. (I'm sure that there are several better threads that include an answer, but I'm unable to find one immediately).

MEF does not support inspecting the part type of a lazy import (without instantiating that part) out of the box. This is probably because of two elements in its design philosophy:

MEF encourages loose coupling. You should specify and use imports based on their contract. Relying on the actual class type of an import would prevent you from changing the composition in the future.

MEF allows for lazy loading of types. Suppose there would be a Lazy.PartType property which you can use to inspect he actual type of the part. This would force the part type and the containing assembly to be loaded. Then you decide based on the PartType that you don't want to instantiate that particular part, and the assembly load was for nothing.

(As far as I can tell, currently MEF does not yet exploit the second design feature out of the box. AssemblyCatalog will inspect all types immediately when AssemblyCatalog.Parts is called anyway. But there is a sample in the MEF sources that shows how to cache information about assemblies to delay or avoid assembly loads.)

So instead of relying on the exact type of the part, you should add some metadata that you can use to do the selection of an import.

Body:
Is it possible get the assembly information from an imported MEF Type, without instantiating a type? I need to know the assembly name and version of the Plugin control that contains the Type. Tried the following, but it just returns the System.ComponentModel.Composition.

foreach (Lazy<UserControl, IMetadata> content in contents)
{
    // get assembly information of the Plugin control for the imported function
    string definingAssembly = content.GetType().Assembly.GetName();
    Console.WriteLine(definingAssembly);
}

To avoid maintenance issues if possible I want to avoid specifying this information in Metadata.


问:
Not matched rows in B join with some row in A
Example data:

```<code>Table1     Table2
x | y      x | y
-----      -----
1 | A      1 | A
1 | B      1 | D
1 | C      2 | M
1 | null   2 | N
2 | M      2 | M
2 | N      1 | A
</code>```

I want to count number of x's in Table2 and join it with Table1. But in Table2 I can have y's which doesn't match to y's in Table1. In this case I want to join them with row with null in y column in Table1.
In an example Table2.1-D should be joined with Tabl1.1-null

For given example I expect the result:

```<code>x | y    | count
-----------------
1 | A    | 2
1 | B    | 0
1 | C    | 0
1 | null | 1 (because D doesn't match to anything else in Table1)
2 | M    | 2
2 | N    | 1
</code>```

答:
This is the best I came up with:</p>

```<code>SELECT t1.x
, t1.y
, [count] = ISNULL(t2.cnt,0)
FROM #Table1 t1
LEFT JOIN (SELECT x
            , y
            , cnt = COUNT(*)
            FROM #Table2
            GROUP BY x, y
        ) t2
ON (t1.x = t2.x
        AND t1.y = t2.y
        AND t1.y IS NOT NULL
    )
    OR (t1.x = t2.x
        AND ISNULL(t1.y,t2.y) = t2.y
        AND NOT EXISTS (SELECT 1 FROM #Table1 WHERE y = t2.y)
    )
</code>```

Body:
Example data:

Table1     Table2
x | y      x | y
-----      -----
1 | A      1 | A
1 | B      1 | D
1 | C      2 | M
1 | null   2 | N
2 | M      2 | M
2 | N      1 | A

I want to count number of x's in Table2 and join it with Table1. But in Table2 I can have y's which doesn't match to y's in Table1. In this case I want to join them with row with null in y column in Table1.
In an example Table2.1-D should be joined with Tabl1.1-null

For given example I expect the result:

x | y    | count
-----------------
1 | A    | 2
1 | B    | 0
1 | C    | 0
1 | null | 1 (because D doesn't match to anything else in Table1)
2 | M    | 2
2 | N    | 1

Body:
This is the best I came up with:

SELECT t1.x
, t1.y
, [count] = ISNULL(t2.cnt,0)
FROM #Table1 t1
LEFT JOIN (SELECT x
            , y
            , cnt = COUNT(*)
            FROM #Table2
            GROUP BY x, y
        ) t2
ON (t1.x = t2.x
        AND t1.y = t2.y
        AND t1.y IS NOT NULL
    )
    OR (t1.x = t2.x
        AND ISNULL(t1.y,t2.y) = t2.y
        AND NOT EXISTS (SELECT 1 FROM #Table1 WHERE y = t2.y)
    )


问:
osgi.wiring.package; (&(osgi.wiring.package=org.json)(version>=0.0.0)) Unresolved requirements:

I am compiling a java plugin that uses org.json. Before I included this the plugin was able to compiling and run correctly. I have seen similar problems on stackoverflow, but none of them address this problem using gradle.

In the top of my classes I have the following

```<code>import org.json.JSONArray;
import org.json.JSONObject;
</code>```

My gradle build script contains the following:

```<code>repositories {
    maven {
        url "http://repo.dotcms.com/artifactory/libs-release"
    }
    mavenCentral()
    flatDir {
        dirs 'src/main/resources/localLibs'
    }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile fileTree(dir: 'src/main/resources/libs', include: '*.jar')
    compile (group: 'com.dotcms', name: 'dotcms', version: '4.2.2'){
        transitive = true
    }
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.8'
    compile group: 'org.json', name: 'json', version: '20170516'
    compile group: 'org.simpleflatmapper', name: 'sfm-csv', version: '3.14.1'
    /* Specifying an alternate configuration (see above 'configurations') keeps servlet-api.jar from being added to our own output Jar. */
    providedCompile "javax.servlet:javax.servlet-api:3.1.0"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

jar {
    manifest {
        name = 'Symplicity SOAP API Web Service'
        symbolicName = 'Symplicity SOAP API Web Service'
        instruction 'Bundle-Vendor', 'JustinKubicek'
        instruction 'Bundle-Name', 'Symplicity SOAP API Web Service'
        instruction 'Bundle-Description', 'This is a plugin to access the Symplicity SOAP API Web Service'
        instruction 'Bundle-DocURL', 'https://bitbucket.org/justinkubicek/symplicity-soap-api-plugin'
        instruction 'Bundle-Activator', 'com.symplicitysoapapi.soapapitool.osgi.Activator'
        instruction 'DynamicImport-Package', '*'
        instruction 'Import-Package', '*;version=0;'
    }
}
</code>```

The error I am getting is this here.

```<code>javax.servlet.ServletException: Unable to resolve Symplicity SOAP API Web Service
[197](R 197.0): missing requirement [Symplicity SOAP API Web Service [197](R 197.0)]
osgi.wiring.package; (&(osgi.wiring.package=org.json)(version>=0.0.0))
Unresolved requirements: [[Symplicity SOAP API Web Service [197](R 197.0)]
osgi.wiring.package; (&(osgi.wiring.package=org.json)(version>=0.0.0))]
Unable to start bundle
at com.dotmarketing.portlets.osgi.AJAX.OSGIAJAX.start(OSGIAJAX.java:122)
~[dotcms_4.2.2_999999.jar:?]
</code>```

答:
Unless you need a custom version of the JSON libraries, I would recommend changing your imports to use the repackaged classes that are included in dotCMS libraries.  The classes there are repackaged to allow developers to include custom versions of this library if needed.  Here is a list of the json classes available in the 4.2.2 release:

./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/XMLTokener.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/XML.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/Test.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONWriter.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONTokener.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONStringer.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONString.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONObject.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONML.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONException.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONArray.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/HTTPTokener.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/HTTP.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/CookieList.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/Cookie.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/CDL.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/```

Of course to use these classes at runtime you need to make sure they are listed in your Exported Packages list:  https://dotcms.com/docs/latest/osgi-plugins#ExportedPackages

Body:
I am compiling a java plugin that uses org.json. Before I included this the plugin was able to compiling and run correctly. I have seen similar problems on stackoverflow, but none of them address this problem using gradle.

In the top of my classes I have the following

import org.json.JSONArray;
import org.json.JSONObject;

My gradle build script contains the following:

repositories {
    maven {
        url "http://repo.dotcms.com/artifactory/libs-release"
    }
    mavenCentral()
    flatDir {
        dirs 'src/main/resources/localLibs'
    }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile fileTree(dir: 'src/main/resources/libs', include: '*.jar')
    compile (group: 'com.dotcms', name: 'dotcms', version: '4.2.2'){
        transitive = true
    }
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.8'
    compile group: 'org.json', name: 'json', version: '20170516'
    compile group: 'org.simpleflatmapper', name: 'sfm-csv', version: '3.14.1'
    /* Specifying an alternate configuration (see above 'configurations') keeps servlet-api.jar from being added to our own output Jar. */
    providedCompile "javax.servlet:javax.servlet-api:3.1.0"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

jar {
    manifest {
        name = 'Symplicity SOAP API Web Service'
        symbolicName = 'Symplicity SOAP API Web Service'
        instruction 'Bundle-Vendor', 'JustinKubicek'
        instruction 'Bundle-Name', 'Symplicity SOAP API Web Service'
        instruction 'Bundle-Description', 'This is a plugin to access the Symplicity SOAP API Web Service'
        instruction 'Bundle-DocURL', 'https://bitbucket.org/justinkubicek/symplicity-soap-api-plugin'
        instruction 'Bundle-Activator', 'com.symplicitysoapapi.soapapitool.osgi.Activator'
        instruction 'DynamicImport-Package', '*'
        instruction 'Import-Package', '*;version=0;'
    }
}

The error I am getting is this here.

javax.servlet.ServletException: Unable to resolve Symplicity SOAP API Web Service
[197](R 197.0): missing requirement [Symplicity SOAP API Web Service [197](R 197.0)]
osgi.wiring.package; (&(osgi.wiring.package=org.json)(version>=0.0.0))
Unresolved requirements: [[Symplicity SOAP API Web Service [197](R 197.0)]
osgi.wiring.package; (&(osgi.wiring.package=org.json)(version>=0.0.0))]
Unable to start bundle
at com.dotmarketing.portlets.osgi.AJAX.OSGIAJAX.start(OSGIAJAX.java:122)
~[dotcms_4.2.2_999999.jar:?]

Body:
Unless you need a custom version of the JSON libraries, I would recommend changing your imports to use the repackaged classes that are included in dotCMS libraries.  The classes there are repackaged to allow developers to include custom versions of this library if needed.  Here is a list of the json classes available in the 4.2.2 release:

./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/XMLTokener.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/XML.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/Test.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONWriter.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONTokener.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONStringer.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONString.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONObject.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONML.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONException.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/JSONArray.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/HTTPTokener.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/HTTP.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/CookieList.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/Cookie.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/CDL.java
./dotserver/tomcat-8.0.18/webapps/ROOT/WEB-INF/lib/dot.json-ukv_2.jar:com/dotcms/repackage/org/json/

Of course to use these classes at runtime you need to make sure they are listed in your Exported Packages list:  https://dotcms.com/docs/latest/osgi-plugins#ExportedPackages


问:
react-google-maps and google event listeners - how to catch events?
In my app I'm using react-google-maps (v.6.x.x) to handle api for Google Maps. I'm using markers and infobox to show proper information. Infobox with enableEventPropagation set to true, propagates events to map layer through the infobox - what does that mean? When I have infobox - aka infowindow whe I click on it, and underneath is placed marker, this marker is 'clicked' in first place, and than any html element in infobox. If enableEventPropagation is false - nothing is propagated. So my question is - is there any possibility to add google event listener for react component, for example code:

```<code>let infobox = (<InfoBox
  onDomReady={() => props.infoBoxReady(infobox)}
  defaultPosition={new google.maps.LatLng(props.activeMarker.location[1], props.activeMarker.location[0])}
  options={{
    closeBoxURL: ``, enableEventPropagation: true, pane: 'mapPane',
    position: new google.maps.LatLng(props.activeMarker.location[1], props.activeMarker.location[0]),
    alignBottom: true,
    pixelOffset: new google.maps.Size(-120, 0)
  }}>
</code>```

How I can use this code to use Google Event Listener

```<code>google.maps.event.addListener(infobox, 'domready', function ()
</code>```

Im getting this kind error

Any clue, how can I set listener for it, or maybe there are other options to set listeners for google map - unfortunately I've to use this library and handle clicks on infobox

答:
I wrote this wrapper component that places a <Rectangle/> over the entire map to stop clicks being passed through to the map below. Whilst still allowing you to click things inside the <infoBox/>.

This allows enableEventPropagation to be set to true without creating problems. I then use mouseOver and mouseOut to control how the rectangle works. In my case I use clicking on the rectangle to close my <InfoBox/>. You could just as easily hide and show it.

```<code>/* global google */
/* eslint-disable jsx-a11y/no-static-element-interactions */

import React from 'react';
import PropTypes from 'prop-types';
import { Rectangle } from 'react-google-maps';
import GoogleInfoBox from 'react-google-maps/lib/components/addons/InfoBox';

const cardWidth = 235;
const boxShadow = 25; // space for outer shadow
const iconHeight = 2; // the actual height is 48px but we use 6px instead to hide the icon but keep it's shadow

class InfoBox extends React.Component {
  constructor(props) {
    super(props);
    this.closable = true;
  }

  onClose = () => {
    if (this.closable) this.props.onClose();
  }

  onHover = () => {
    this.closable = false;
  }

  onMouseOut = () => {
    this.closable = true;
  }

  render() {
    const { children, position, onClose, type } = this.props;

    return (
      <div className="info-box">
        <Rectangle
          options={{ fillColor: '#ffffff', fillOpacity: 0.7, zIndex: 100 }}
          bounds={{ north: 90, south: -90, east: 180, west: -180 }}
          onClick={this.onClose}
        />
        <GoogleInfoBox
          position={new google.maps.LatLng(position.lat, position.lng)}
          onCloseClick={onClose}
          options={{
            alignBottom: true,
            disableAutoPan: false,
            pixelOffset: new google.maps.Size(-(cardWidth / 2) - boxShadow, -iconHeight),
            maxWidth: width,
            isHidden: false,
            visible: true,
            pane: 'floatPane',
            enableEventPropagation: true,
          }}
        >
          <div
            onMouseOver={this.onHover}
            onFocus={this.onHover}
            onMouseOut={this.onMouseOut}
            onBlur={this.onMouseOut}
          >
            { children }
          </div>
        </GoogleInfoBox>
      </div>
    );
  }
}

InfoBox.propTypes = {
  children: PropTypes.element.isRequired,
  position: PropTypes.shape({
    lat: PropTypes.number.isRequired,
    lng: PropTypes.number.isRequired,
  }).isRequired,
  onClose: PropTypes.func,
  type: PropTypes.string,
};

export default InfoBox;
</code>```

Body:
In my app I'm using react-google-maps (v.6.x.x) to handle api for Google Maps. I'm using markers and infobox to show proper information. Infobox with enableEventPropagation set to true, propagates events to map layer through the infobox - what does that mean? When I have infobox - aka infowindow whe I click on it, and underneath is placed marker, this marker is 'clicked' in first place, and than any html element in infobox. If enableEventPropagation is false - nothing is propagated. So my question is - is there any possibility to add google event listener for react component, for example code:

let infobox = (<InfoBox
  onDomReady={() => props.infoBoxReady(infobox)}
  defaultPosition={new google.maps.LatLng(props.activeMarker.location[1], props.activeMarker.location[0])}
  options={{
    closeBoxURL: ``, enableEventPropagation: true, pane: 'mapPane',
    position: new google.maps.LatLng(props.activeMarker.location[1], props.activeMarker.location[0]),
    alignBottom: true,
    pixelOffset: new google.maps.Size(-120, 0)
  }}>

How I can use this code to use Google Event Listener

google.maps.event.addListener(infobox, 'domready', function ()

Im getting this kind error

Any clue, how can I set listener for it, or maybe there are other options to set listeners for google map - unfortunately I've to use this library and handle clicks on infobox

Body:
I wrote this wrapper component that places a <Rectangle/> over the entire map to stop clicks being passed through to the map below. Whilst still allowing you to click things inside the <infoBox/>.

This allows enableEventPropagation to be set to true without creating problems. I then use mouseOver and mouseOut to control how the rectangle works. In my case I use clicking on the rectangle to close my <InfoBox/>. You could just as easily hide and show it.

/* global google */
/* eslint-disable jsx-a11y/no-static-element-interactions */

import React from 'react';
import PropTypes from 'prop-types';
import { Rectangle } from 'react-google-maps';
import GoogleInfoBox from 'react-google-maps/lib/components/addons/InfoBox';

const cardWidth = 235;
const boxShadow = 25; // space for outer shadow
const iconHeight = 2; // the actual height is 48px but we use 6px instead to hide the icon but keep it's shadow

class InfoBox extends React.Component {
  constructor(props) {
    super(props);
    this.closable = true;
  }

  onClose = () => {
    if (this.closable) this.props.onClose();
  }

  onHover = () => {
    this.closable = false;
  }

  onMouseOut = () => {
    this.closable = true;
  }

  render() {
    const { children, position, onClose, type } = this.props;

    return (
      <div className="info-box">
        <Rectangle
          options={{ fillColor: '#ffffff', fillOpacity: 0.7, zIndex: 100 }}
          bounds={{ north: 90, south: -90, east: 180, west: -180 }}
          onClick={this.onClose}
        />
        <GoogleInfoBox
          position={new google.maps.LatLng(position.lat, position.lng)}
          onCloseClick={onClose}
          options={{
            alignBottom: true,
            disableAutoPan: false,
            pixelOffset: new google.maps.Size(-(cardWidth / 2) - boxShadow, -iconHeight),
            maxWidth: width,
            isHidden: false,
            visible: true,
            pane: 'floatPane',
            enableEventPropagation: true,
          }}
        >
          <div
            onMouseOver={this.onHover}
            onFocus={this.onHover}
            onMouseOut={this.onMouseOut}
            onBlur={this.onMouseOut}
          >
            { children }
          </div>
        </GoogleInfoBox>
      </div>
    );
  }
}

InfoBox.propTypes = {
  children: PropTypes.element.isRequired,
  position: PropTypes.shape({
    lat: PropTypes.number.isRequired,
    lng: PropTypes.number.isRequired,
  }).isRequired,
  onClose: PropTypes.func,
  type: PropTypes.string,
};

export default InfoBox;


问:
python 3 function with one argument returning list of integers
how the 're' function should look like if it must receive just one argument 's' and must return a list with the numbers (integers) from 1 to 12 incl. (for example)?

so the result in the interactive console have to be:

```<code>>>> re(12)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
</code>```

答:
I would avoid using "re" as a function name, since re is also a python library for regex expressions.

Lycopersicum's answer does a good job of explaining range(), which is the fastest and most straight-forward way of approaching your problem. In general, it is best to use Python's built-in functions, that's because it will use Python's compiled C code rather than slower Python code.

I just thought I'd share a little bit about why you should use Range().

So, there are other ways to generate a list of numbers.  First generate a list directly using a loop.

```<code>def listOfNumbers (number):
  start = 1
  listOf = []
  while (start <= number):
    listOf.append(start)
    start = start + 1
    return listOf
</code>```

In this case, you simply use listOfNumbers(12) and you will get a list of numbers.  However, this stores a list in memory and is slow, so not good for very large numbers.

On the other hand, you could use a generator (which is very much like range()).  A generator does not store data in a list.  Instead, it just "yields" numbers one at a time until the code stops.  It's much faster:

```<code>def generatorOfNumbers (number):
 start = 1
 while start <= number:
   yield start
   start += 1
</code>```

Then you can call it one of two ways to produce a list:

```<code>def listFromGenerator1 (number):
  return [x for x in generatorOfNumbers(number)]

def listFromGenerator2 (number):
  return list(generatorOfNumbers (number))
</code>```

When I time these approaches I get.

```<code>timed(listOfNumbers) # time for list of 10000
...
Elapsed Time: 2.16007232666
Elapsed Time: 1.32894515991
Elapsed Time: 2.09093093872
Elapsed Time: 1.99699401855
Elapsed Time: 3.2000541687

...   timed(listFromGenerator1)
...
Elapsed Time: 1.33109092712
Elapsed Time: 1.30605697632
Elapsed Time: 1.93309783936
Elapsed Time: 1.79386138916
Elapsed Time: 1.90401077271

...   timed(listFromGenerator2)
...
Elapsed Time: 0.869989395142
Elapsed Time: 1.08408927917
Elapsed Time: 1.65319442749
Elapsed Time: 1.53398513794
Elapsed Time: 1.36089324951

...   timed(listFromRange)  # Lycopersicum's approach
...
Elapsed Time: 0.346899032593
Elapsed Time: 0.284194946289
Elapsed Time: 0.282049179077
Elapsed Time: 0.295877456665
Elapsed Time: 0.303983688354
</code>```

In conclusion, always use built-in functions whenever possible rather than trying to build your own.  That includes the (slight) preference for list() vs a list comprehension.

Body:
how the 're' function should look like if it must receive just one argument 's' and must return a list with the numbers (integers) from 1 to 12 incl. (for example)?

so the result in the interactive console have to be:

>>> re(12)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Body:
I would avoid using "re" as a function name, since re is also a python library for regex expressions.

Lycopersicum's answer does a good job of explaining range(), which is the fastest and most straight-forward way of approaching your problem. In general, it is best to use Python's built-in functions, that's because it will use Python's compiled C code rather than slower Python code.

I just thought I'd share a little bit about why you should use Range().

So, there are other ways to generate a list of numbers.  First generate a list directly using a loop.

def listOfNumbers (number):
  start = 1
  listOf = []
  while (start <= number):
    listOf.append(start)
    start = start + 1
    return listOf

In this case, you simply use listOfNumbers(12) and you will get a list of numbers.  However, this stores a list in memory and is slow, so not good for very large numbers.

On the other hand, you could use a generator (which is very much like range()).  A generator does not store data in a list.  Instead, it just "yields" numbers one at a time until the code stops.  It's much faster:

def generatorOfNumbers (number):
 start = 1
 while start <= number:
   yield start
   start += 1

Then you can call it one of two ways to produce a list:

def listFromGenerator1 (number):
  return [x for x in generatorOfNumbers(number)]

def listFromGenerator2 (number):
  return list(generatorOfNumbers (number))

When I time these approaches I get.

timed(listOfNumbers) # time for list of 10000
...
Elapsed Time: 2.16007232666
Elapsed Time: 1.32894515991
Elapsed Time: 2.09093093872
Elapsed Time: 1.99699401855
Elapsed Time: 3.2000541687

...   timed(listFromGenerator1)
...
Elapsed Time: 1.33109092712
Elapsed Time: 1.30605697632
Elapsed Time: 1.93309783936
Elapsed Time: 1.79386138916
Elapsed Time: 1.90401077271

...   timed(listFromGenerator2)
...
Elapsed Time: 0.869989395142
Elapsed Time: 1.08408927917
Elapsed Time: 1.65319442749
Elapsed Time: 1.53398513794
Elapsed Time: 1.36089324951

...   timed(listFromRange)  # Lycopersicum's approach
...
Elapsed Time: 0.346899032593
Elapsed Time: 0.284194946289
Elapsed Time: 0.282049179077
Elapsed Time: 0.295877456665
Elapsed Time: 0.303983688354

In conclusion, always use built-in functions whenever possible rather than trying to build your own.  That includes the (slight) preference for list() vs a list comprehension.


问:
How to Save Excel Worksheet as PDF with Command Button?
I am getting a 'Syntax Error' with the coding beneath the Next R line toward the bottom below.  I am trying to save the open worksheet as a PDF file referencing the order number found in cell D3.  Thanks for your help!</p>

```<code>Private Sub CommandButton1_Click()
Dim OrderDate As String, PONumber As String, Vendor As String, ShipTo As String, SKU As String, Path As String, filename As String
Dim R As Long, LastSKURow As Long, NextDBRow As Long, OFrm As Worksheet, DB As Worksheet
Set OFrm = Worksheets("Order Form 1")
Set DB = Worksheets("Database")
OrderDate = OFrm.Range("B3")
PONumber = OFrm.Range("D3")
Vendor = OFrm.Range("B7")
ShipTo = OFrm.Range("D7")
LastSKURow = OFrm.Cells(OFrm.Rows.Count, "F").End(xlUp).Row
For R = 3 To LastSKURow
    SKU = OFrm.Range("F" & R).Value
    NextDBRow = DB.Cells(DB.Rows.Count, "A").End(xlUp).Row + 1
    DB.Range("A" & NextDBRow).Value = OrderDate
    DB.Range("B" & NextDBRow).Value = PONumber
    DB.Range("C" & NextDBRow).Value = Vendor
    DB.Range("D" & NextDBRow).Value = ShipTo
    DB.Range("E" & NextDBRow).Value = SKU
Next R
Application.ScreenUpdating = False
OFrm.ExportAsFixedFormat Type:=xlTypePDF, _
        Path ="C:\PDF\"
        filename = OFrm.Range("D3")
        OpenAfterPublish = False
OFRrm.SaveAs filename:=Path & filename & ".pdf", FileFormat:=xlTypePDF
End Sub
</code>```

答:
I think that your variable "filename" is conflicting with the method keyword "Filename". Call your variable something else...

```<code>OFRrm.SaveAs Filename:= Path & myFile & ".pdf", FileFormat:=xlTypePDF
</code>```

or just eliminate the keywords in the arguments altogether:

```<code>OFRrm.SaveAs Path & myFile & ".pdf", xlTypePDF
</code>```

Body:
I am getting a 'Syntax Error' with the coding beneath the Next R line toward the bottom below.  I am trying to save the open worksheet as a PDF file referencing the order number found in cell D3.  Thanks for your help!

Private Sub CommandButton1_Click()
Dim OrderDate As String, PONumber As String, Vendor As String, ShipTo As String, SKU As String, Path As String, filename As String
Dim R As Long, LastSKURow As Long, NextDBRow As Long, OFrm As Worksheet, DB As Worksheet
Set OFrm = Worksheets("Order Form 1")
Set DB = Worksheets("Database")
OrderDate = OFrm.Range("B3")
PONumber = OFrm.Range("D3")
Vendor = OFrm.Range("B7")
ShipTo = OFrm.Range("D7")
LastSKURow = OFrm.Cells(OFrm.Rows.Count, "F").End(xlUp).Row
For R = 3 To LastSKURow
    SKU = OFrm.Range("F" & R).Value
    NextDBRow = DB.Cells(DB.Rows.Count, "A").End(xlUp).Row + 1
    DB.Range("A" & NextDBRow).Value = OrderDate
    DB.Range("B" & NextDBRow).Value = PONumber
    DB.Range("C" & NextDBRow).Value = Vendor
    DB.Range("D" & NextDBRow).Value = ShipTo
    DB.Range("E" & NextDBRow).Value = SKU
Next R
Application.ScreenUpdating = False
OFrm.ExportAsFixedFormat Type:=xlTypePDF, _
        Path ="C:\PDF\"
        filename = OFrm.Range("D3")
        OpenAfterPublish = False
OFRrm.SaveAs filename:=Path & filename & ".pdf", FileFormat:=xlTypePDF
End Sub

Body:
I think that your variable "filename" is conflicting with the method keyword "Filename". Call your variable something else...

OFRrm.SaveAs Filename:= Path & myFile & ".pdf", FileFormat:=xlTypePDF

or just eliminate the keywords in the arguments altogether:

OFRrm.SaveAs Path & myFile & ".pdf", xlTypePDF


问:
How to overwrite existing .rar archive on adding files and folders to an archive?
I'm using WinRAR command line for archiving files into a predefined location with the name of the date like: 20171206.rar
When I rerun the command, I want the RAR file to be replaced and not updated. I went through the list of WinRAR command line switches but found nothing that gets me the desired result.

Any and all comments are welcome.

答:
WinRAR has no command or switch to ignore an existing archive file on compressing files and folders into an archive like all compression tools I'm aware of.

WinRAR has the command d to delete files in an archive with deleting the archive file itself on finally not containing any file. But I think it is not advisable to use WinRAR with command d to just delete an archive file before creating a new archive file with same name.

I use for archiving source files the switch -agYYYY-MM-DD_NN making it possible for me to create more than one individual archive per day for backup purposes. WinRAR automatically creates RAR archive files with current date in format yyyy-MM-dd in file name with an incremented number because of NN, i.e. 2017-12-06_01.rar, 2017-12-06_02.rar, ...,  2017-12-07_01.rar, and so on. I delete manually the backup archives no longer needed from time to time.

I suggest the following batch file for your task:

```<code>@echo off
if not exist "20??????.rar" goto CreateDayArchive
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "FileNameDate=%%I"
del "%FileNameDate:~0,8%.rar" 2>nul
set "FileNameDate="

:CreateDayArchive
rem The RAR/WinRAR command line to create the new archive with current date.
</code>```

The FOR command line to get current date in format yyyyMMdd region independent is explained in detail for example at Why does %date% produce a different result in batch file executed as scheduled task?

The usage of the environment variable DATE would be much faster than using the command WMIC. But the date format of the environment variable DATE depends on Windows region and language settings. On my computer the date value of the environment variable DATE is always in format dd.MM.yyyy which makes it possible to use this much faster batch file:

```<code>@echo off
del "%DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%.rar" 2>nul
rem The RAR/WinRAR command line to create the new archive with current date.
</code>```

This code works also with / or - as separator instead of . as well as for date strings with abbreviated weekday at beginning because year, month and day are substituted from DATE string from right side. So a date like Wed, 06/12/2017 (6th December 2017) would be also processed correct by this fast batch code variant.

If the region dependent date format of DATE is MM/dd/yyyy without or with abbreviated weekday at beginning, the following batch file could be used with day and month substitution exchanged.

```<code>@echo off
del "%DATE:~-4%%DATE:~-10,2%%DATE:~-7,2%.rar" 2>nul
rem The RAR/WinRAR command line to create the new archive with current date.
</code>```

See also answer on What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean? for a complete explanation on date string substitution to reformat region dependent DATE value into the wanted date format.

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

del /?

echo /?

for /?

goto /?

if /?

rem /?

set /?

wmic /?

wmic os /?

wmic os get /?

wmic os get localdatetime /?

Read also the Microsoft article about Using command redirection operators for an explanation of 2>nul used here to suppress the error message output by DEL to handle STDERR by redirecting it to device NUL if there is no RAR archive file with current date in file name in the current directory.

Body:
WinRAR has no command or switch to ignore an existing archive file on compressing files and folders into an archive like all compression tools I'm aware of.

WinRAR has the command d to delete files in an archive with deleting the archive file itself on finally not containing any file. But I think it is not advisable to use WinRAR with command d to just delete an archive file before creating a new archive file with same name.

I use for archiving source files the switch -agYYYY-MM-DD_NN making it possible for me to create more than one individual archive per day for backup purposes. WinRAR automatically creates RAR archive files with current date in format yyyy-MM-dd in file name with an incremented number because of NN, i.e. 2017-12-06_01.rar, 2017-12-06_02.rar, ...,  2017-12-07_01.rar, and so on. I delete manually the backup archives no longer needed from time to time.

I suggest the following batch file for your task:

@echo off
if not exist "20??????.rar" goto CreateDayArchive
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "FileNameDate=%%I"
del "%FileNameDate:~0,8%.rar" 2>nul
set "FileNameDate="

:CreateDayArchive
rem The RAR/WinRAR command line to create the new archive with current date.

The FOR command line to get current date in format yyyyMMdd region independent is explained in detail for example at Why does %date% produce a different result in batch file executed as scheduled task?

The usage of the environment variable DATE would be much faster than using the command WMIC. But the date format of the environment variable DATE depends on Windows region and language settings. On my computer the date value of the environment variable DATE is always in format dd.MM.yyyy which makes it possible to use this much faster batch file:

@echo off
del "%DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%.rar" 2>nul
rem The RAR/WinRAR command line to create the new archive with current date.

This code works also with / or - as separator instead of . as well as for date strings with abbreviated weekday at beginning because year, month and day are substituted from DATE string from right side. So a date like Wed, 06/12/2017 (6th December 2017) would be also processed correct by this fast batch code variant.

If the region dependent date format of DATE is MM/dd/yyyy without or with abbreviated weekday at beginning, the following batch file could be used with day and month substitution exchanged.

@echo off
del "%DATE:~-4%%DATE:~-10,2%%DATE:~-7,2%.rar" 2>nul
rem The RAR/WinRAR command line to create the new archive with current date.

See also answer on What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean? for a complete explanation on date string substitution to reformat region dependent DATE value into the wanted date format.

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

del /?

echo /?

for /?

goto /?

if /?

rem /?

set /?

wmic /?

wmic os /?

wmic os get /?

wmic os get localdatetime /?

Read also the Microsoft article about Using command redirection operators for an explanation of 2>nul used here to suppress the error message output by DEL to handle STDERR by redirecting it to device NUL if there is no RAR archive file with current date in file name in the current directory.


问:
How to create multiple autocomplete in an input field based on a sentence structure?
The sentence structure of my autocomplete is:

<Occupation> <for> <time period>

Example:

Student for 5 years

Teacher for 2 years

In the database, I have a column containing a list of occupations. With jQuery UI autocomplete, I populate the first two sections   in the text input using the following codes:

```<code><script>
    $(function() {
        $("#occupation").autocomplete({
            source: 'search.php',
            delay: 500,
            select: function(event, ui) {
                $(this).val(ui.item.value)
            }
        });
    });
</script>
<input type='text' name='occupation' id='occupation’>
</code>```

The search.php code:

```<code><?php
$searchTerm = $_GET['term'];
$query = $db->query("SELECT DISTINCT occupation FROM table WHERE occupation LIKE '%" . $searchTerm . "%' ORDER BY occupation ASC");
$a_json = array();

while ($row = $query->fetch_assoc())
    {
    $data_row["value"] = $row['occupation'] . ' for';
    $data_row["label"] = $row['occupation'];
    array_push($a_json, $data_row);
    }

echo json_encode($a_json);
</code>```

Now, is there any way to create a second trigger to make an autocomplete for the rest? Like after selecting an occupation, if the user inputs 5, it’ll show the following autocomplete options for the time period: 5 days/ 5 weeks/ 5 months/ 5 years. Like the image below:

Thanks in advance for your suggestions.

答:
You can parse the query, when you have a number (as we don't have words with numbers yet) you could make the call to autocomplete again.

Example:

```<code>$number = preg_replace('/\D/', '', $query); // replaces every non number for empty string
if (is_numeric($number))
{
    $output = '';
    // return variations like you want
    foreach (array ('weeks', 'years') as $period)
    {
        $output .= $number . $period;
    }
    return $output;
}
</code>```

Body:
The sentence structure of my autocomplete is:

<Occupation> <for> <time period>

Example:

Student for 5 years

Teacher for 2 years

In the database, I have a column containing a list of occupations. With jQuery UI autocomplete, I populate the first two sections   in the text input using the following codes:

<input type='text' name='occupation' id='occupation’>

The search.php code:

<?php
$searchTerm = $_GET['term'];
$query = $db->query("SELECT DISTINCT occupation FROM table WHERE occupation LIKE '%" . $searchTerm . "%' ORDER BY occupation ASC");
$a_json = array();

while ($row = $query->fetch_assoc())
    {
    $data_row["value"] = $row['occupation'] . ' for';
    $data_row["label"] = $row['occupation'];
    array_push($a_json, $data_row);
    }

echo json_encode($a_json);

Now, is there any way to create a second trigger to make an autocomplete for the rest? Like after selecting an occupation, if the user inputs 5, it’ll show the following autocomplete options for the time period: 5 days/ 5 weeks/ 5 months/ 5 years. Like the image below:

Thanks in advance for your suggestions.

Body:
You can parse the query, when you have a number (as we don't have words with numbers yet) you could make the call to autocomplete again.

Example:

$number = preg_replace('/\D/', '', $query); // replaces every non number for empty string
if (is_numeric($number))
{
    $output = '';
    // return variations like you want
    foreach (array ('weeks', 'years') as $period)
    {
        $output .= $number . $period;
    }
    return $output;
}


问:
scala: Dynamically filtering with predicates
I have a Map[String, Int]

```<code>val labelMap: mutable.HashMap[String, Int] = sparse0.sparseOperationCountRowsByTarget()
</code>```

I want to filter that map in one statement. The filter may filter both by String or Int

In crudest form it looks like this:

```<code> val labelMapFiltered = labelMap.filter(label => label._1.startsWith("REL") || label._2 < 400)
</code>```

Now I already have general utility predicates for String and Int functions. String predicates are:

```<code>object StringPredicates
{
  def stringEquals(required:String)(input:String) = input == required
  def stringStartsWith(required:String)(input:String) = input.startsWith(required)
  def stringContains(required:String)(input:String) = input.contains(required)

  def and(predicates:Seq[String => Boolean])(input:String) = predicates.forall(predicate => predicate(input))
  def or(predicates:Seq[String => Boolean])(input:String) = predicates.exists(predicate => predicate(input))
}
</code>```

Int predicates are same pattern as above.

This allows for the following filter:

```<code>val sw1=stringContains("#")
val sw2=stringStartsWith("REL")
val sw3=intGT(400)

      val labelMapFiltered = labelMap.filter( label =>sw1(label._1) || sw2(label._1) || sw3(label._2) )
</code>```

I want to pass the predicates into the function (as a Seq, I assume) and then filter.
So I am looking for something like:

```<code>val labelMapFiltered = labelMap.filter( myFunction(myPredSeq))
</code>```

Can I do this using the predicates I already have? Writing predicates for Tuple2[String,Int] that match the specific Map in this function seems too specific. I would then have to write predicates for every type of Map I want to filter.

答:
Let's simplify the input and consider a simple list of Ints:

```<code>List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
</code>```

You can put all your predicates in a Stream (so that they're evaluated lazily and you don't have to evaluate all of them):

```<code>val predicates = Stream((n: Int) => n == 0, (n: Int) => n % 2 == 1, (n: Int) => n >= 8)
</code>```

The rules are that numbers will be kept if they are 0, odd or greater or equal to 8.

Now we ask to filter by looking if there is at least one predicate in our collection that returns true:

```<code>list.filter(n => predicates.exists(p => p(n)))
</code>```

The output is a list of numbers that respect at least one of the rules:

```<code>List(0, 1, 3, 5, 7, 8, 9)
</code>```

Body:
I have a Map[String, Int]

val labelMap: mutable.HashMap[String, Int] = sparse0.sparseOperationCountRowsByTarget()

I want to filter that map in one statement. The filter may filter both by String or Int

In crudest form it looks like this:

 val labelMapFiltered = labelMap.filter(label => label._1.startsWith("REL") || label._2 < 400)

Now I already have general utility predicates for String and Int functions. String predicates are:

object StringPredicates
{
  def stringEquals(required:String)(input:String) = input == required
  def stringStartsWith(required:String)(input:String) = input.startsWith(required)
  def stringContains(required:String)(input:String) = input.contains(required)

  def and(predicates:Seq[String => Boolean])(input:String) = predicates.forall(predicate => predicate(input))
  def or(predicates:Seq[String => Boolean])(input:String) = predicates.exists(predicate => predicate(input))
}

Int predicates are same pattern as above.

This allows for the following filter:

val sw1=stringContains("#")
val sw2=stringStartsWith("REL")
val sw3=intGT(400)

      val labelMapFiltered = labelMap.filter( label =>sw1(label._1) || sw2(label._1) || sw3(label._2) )

I want to pass the predicates into the function (as a Seq, I assume) and then filter.
So I am looking for something like:

val labelMapFiltered = labelMap.filter( myFunction(myPredSeq))

Can I do this using the predicates I already have? Writing predicates for Tuple2[String,Int] that match the specific Map in this function seems too specific. I would then have to write predicates for every type of Map I want to filter.

Body:
Let's simplify the input and consider a simple list of Ints:

List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

You can put all your predicates in a Stream (so that they're evaluated lazily and you don't have to evaluate all of them):

val predicates = Stream((n: Int) => n == 0, (n: Int) => n % 2 == 1, (n: Int) => n >= 8)

The rules are that numbers will be kept if they are 0, odd or greater or equal to 8.

Now we ask to filter by looking if there is at least one predicate in our collection that returns true:

list.filter(n => predicates.exists(p => p(n)))

The output is a list of numbers that respect at least one of the rules:

List(0, 1, 3, 5, 7, 8, 9)