Performing action when closing JFrame

Question: In my program I have a main JFrame that holds a button. When this button is clicked a new JFrame appears in which I can change some information. Whenever I finish editing I press a save button on the new JFrame which saves the changes and disposes the JFrame. Now when this is done, I'd like to perform an action in the main JFrame as well, but only if something changed. If I open the new JFrame and just close it again without using the save button, I don't want to do anything in the main frame.
I've tried searching the web for a solution, but just don't seem to be anything useful out there..
An example of the code I've got so far:
Main Frame...

public class MainFrame extends JFrame
 {
     public MainFrame()
     {
         super("Main Frame");
         JButton details = new JButton("Add Detail");
         add(details);
         details.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e)
             {
                 new DetailFrame().setVisible(true);
             }
         });
     }
 }

Detail Frame...

 public class DetailFrame extends JFrame
 {
     public DetailFrame()
     {
         super("Detail Frame");
         JButton save = new JButton("Save");
         add(save);
         save.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e)
             {
                 // Save whatever content
                 dispose();
             }
         });
     }
 }

So when I click the "Save" button on the Detail Frame, I want to do something in the Main Frame, whereas when the "x" is clicked on the Detail Frame, I don't want to do anything..
Hope someone is able to help me, and sorry for my english..
Answer: You can pass a MainFrame handle to the DetailFrame constructor. Then, on clicking the Save button, the DetailFrame would call a function in MainFrame and pass the changes to it.
Another way is to create a public boolean variable in DetailFrame and set it to true when the Save button is clicked. This way MainFrame will know whether the DetailFrame was closed or Save'd.
EDIT: Some more ideas:
Use JDialog instead of JFrame. JDialog.setVisible is modal, i.e. it will block the calling function until the dialog is closed; this way you can process the results of the dialog in the same "Details" button listener.
To access the dialog after it is called, store the dialog in a separate variable. First construct the dialog, then show it, and then process the result by analyzing its variables.
Store the results of editing in other public variables of DetailFrame (or let's call it DetailDialog). This should happen only when the "Save" button is clicked. This may even allow to go without the boolean variable (depends on the types of values you are editing).
DetailDialog dlg = new DetailDialog();
dlg.setVisible(true);
if(dlg.approvedResult != null) {
    // process the result...
}

EDIT: Sorry, JDialog is not modal by default. Need to call a special super constructor to make it modal.
Also, here you will have to pass the reference to MainFrame to the dialog constructor, but you still can declare it as a simple JFrame and avoid unnecessary dependencies.
To get the reference to the enclosing MainFrame from within the anonymous ActionListener, use MainFrame.this.
To be able to change the button text after it was created, you will have to store the button in a member variable.
Main Frame...
public class MainFrame extends JFrame
{
    private JButton details = new JButton("Add Detail");

    public MainFrame()
    {
        super("Main Frame");
        getContentPane().add(details);
        details.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                DetailDialog dlg = new DetailDialog(MainFrame.this);
                dlg.setVisible(true);
                if(dlg.approved){
                    details.setText("Edit Detail");
                }
            }
        });
    }
}

Detail Dialog... (not Frame)
public class DetailDialog extends JDialog
{
    public boolean approved = false;

    public DetailDialog(JFrame parent)
    {
        super(parent,"Detail Dialog",true);        // modal dialog parented to the calling frame
        JButton save = new JButton("Save");
        getContentPane().add(save);
        save.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                // Save whatever content
                approved = true;
                dispose();
            }
        });
    }
}

Comment: I tried the thing with the public boolean value, but for some reason I just can't access it from the MainFrame..
I'm not sure what you mean by passing a handle to the DetailFrame constructer?
Comment: I edited the answer, please see more details above. In fact, passing the `MainFrame` to the dialog is not the best idea because it adds too many dependencies between classes; the method with public variables is better because it will allow you to use the same dialog in different places.
Comment: I tried the above now, but still doesn't work.. In my code the dialog doesn't seem to be modal - the function that opens the dialog keeps executing right away in stead of waiting until the dialog is closed..
Comment: Finally got it working by calling the setModal(true) function before setting the dialog to be visible.
Comment: @Simon:  "Finally got it working by calling the setModal(true)"  That can be done in the constructor.  BTW - The modality of the dialog was first mentioned in my reply.  Did you miss that?
Comment: @Andrew Thompson: sorry - I must have missed that.. I just figurer tis answer by Goblin was the Best description of the whole thing ;-)
Answer: Create the detail frame in the main frame, and add a windowlistener to it, using the windowadapter class. Implement the windowclosing event by checking for changes, handle those, and then dispose the detail frame. This is all done in the mainframe.
The detail frame should have do nothing on close set to prevent the detail frame being disposed before you recorded the changes.
You may wish to implement checking for changes in the detailframe as a method returning a class holding the interesting data. That way your windowlistener can be small an to the point.
Comment: I don't quite get it.. The exact thing I want to do is, to change the text of the "Add Detail" button to say "Edit detail", but only when a detail is added..
Could you by any chance give a code example of what you described above?
Answer: Forget the 2nd JFrame.  use a modal dialog instead.  It will block input until dismissed.  Once dismissed, the only thing to do is decide whether to update the original data.  JOptionPane has some inbuilt functionality that makes that easy.  If the user presses Cancel or the esc key, the showInputDialog() method will return null as the result.
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

class EditInfo {

    public static void main(String[] args) {

        Runnable r = new Runnable() {
            public void run() {
                final JFrame f = new JFrame("Uneditable");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel p = new JPanel(new BorderLayout(10,10));

                final JTextField tf = new JTextField("Hello World!", 20);
                tf.setEnabled(false);
                p.add(tf, BorderLayout.CENTER);

                JButton edit = new JButton("Edit");
                edit.addActionListener( new ActionListener(){
                    public void actionPerformed(ActionEvent ae) {
                        String result = JOptionPane.showInputDialog(
                            f,
                            "Edit text",
                            tf.getText());
                        if (result!=null) {
                            tf.setText(result);
                        }
                    }
                } );
                p.add(edit, BorderLayout.EAST);

                p.setBorder(new EmptyBorder(10,10,10,10));

                f.setContentPane(p);
                f.pack();
                f.setLocationByPlatform(true);
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

If it is necessary to edit a number of fields all at once in the JOptionPane, use a JPanel to contain them all, and put them in a showMessageDialog() call.  Check the integer based return result to determine if the user OK'd the changes.

Performing action when closing JFrame


Finding the inverse of trig functions

Question: I'm supposed to find the inverse of $$f(x) = \cos(x)+x$$
I usually just substitute $x$ for $y$ and then re-arrange. What do I do in this scenario?
Comment: @Paze You're looking for $x$ such that $f(x)=1$. It's easy to guess.
Comment: Is this part of a bigger problem?
Comment: I'm to find $$f^{-1} (1)$$
Comment: Are you sure you are being asked to **find** the inverse?  There is probably no simple answer to that.  If you only need to **prove the inverse exists** it's not so hard.
Comment: Why would you need to find the inverse to calculate that?
Comment: Sorry, I see I did a typo
Comment: Guess I just don't think of inverses like that...They sometimes boggle me...Thanks.
Answer: You are trying to find $f^{-1}(1)$, which I will have set equal to $a$.
$$f^{-1}(1)=a$$
$$\implies1=f(a)$$
$$1=\cos(x)+x$$
By observation, $x=0$ is a solution.
By graphing, it is the only solution.

Finding the inverse of trig functions


Configuration synchronization page throwing 504 timeout error

Question: This issue is happening on every level above my vagrant local box. It's a brand new website and a few days back I had to copy my database from local to staging environment. Once done, I ran drush -cim to import the files from config/sync directory into the database.
no error while running the drush -cim command and also all the UUIDs match from local to staging environment. However, on loading the config/sync page in the front end, I constantly see 504 timeout error. Screenshot as below:

The watchdog does not have any error and I saw just one error message:

This error is not constant and I am unable to reproduce this error as well. any help on how I can bring the config/sync page back up??
Comment: I wouldn't have thought so, not directly anyway. Stuff like this usually comes down to server config or resource/memory problems in my experience
Comment: A 504 is a server error, not thrown by Drupal - you'll need to to dig through your server logs to find the issue
Comment: Probably yes, but it depends on your setup. If you've got varnish for example check its logs, if you're using PHP FPM check those logs, and so on
Comment: Understood. Server log means Apache log right?
Comment: Ok, I'll do that. This doesn't have anything to do with config files UUIDs right?
Comment: ok i'll check server logs
Answer: Finally, I got this fixed. Apache log did not have any evidence for this issue. However, on the config/sync page in the 'Import' tab, I saw an error as "/var/www/html/config/sync" folder is not writable. Making this folder permission to 760 fixed the issue for me.


What causes my problem when trying to create multiple tables in hook_schema?

Question: I'm working on a module that has 2 tables and this is my code:
function gen_schema(){
$schema = array();

//table cv
$schema['cv'] = array(
        'description' => 'table contenant les cv.',
        'fields' => array(
                'cvid' => array(
                        'description' => 'clé primaire de la table cv.',
                        'type' => 'serial',
                        'unsigned' => TRUE,
                        'not null' => TRUE,
                ),

                'uid' => array(
                        'type' => 'int',
                        'unsigned' => TRUE,
                        'not null' => TRUE,
                        'description' => 'Primary Key: Unique user ID.',
                        'default' => 0,
                ),
        ),

        'foreign keys' => array(
                'node_cv' => array(
                        'table' => 'node_revision',
                        'columns' => array('vid' => 'vid'),
                ),
        ),

        'primary key' => array('cvid'),
);

//table Information generale
$schema['information'] = array(
        'description' => 'table contenant les informations generales d\'un cv.',
        'fields' => array(
                'infoid' => array(
                        'description' => 'clé primaire de la table information.',
                        'type' => 'serial',
                        'unsigned' => TRUE,
                        'not null' => TRUE,
                ),

                'cvid' => array(
                        'description' => 'clé primaire de la table cv.',
                        'type' => 'serial',
                        'unsigned' => TRUE,
                        'not null' => TRUE,
                ),

                'uid' => array(
                        'type' => 'int',
                        'unsigned' => TRUE,
                        'not null' => TRUE,
                        'description' => 'Primary Key: Unique user ID.',
                        'default' => 0,
                ),

                'nom' => array(
                        'description' => 'nom et prenom du proprietaire du cv.',
                        'type' => 'varchar',
                        'length' => 120,
                        'not null' => TRUE,
                        'default' => '',
                ),

                'nationalite' => array(
                        'description' => 'nationalité du proprietaire du cv.',
                        'type' => 'varchar',
                        'length' => 120,
                        'not null' => TRUE,
                        'default' => '',
                ),

                'profession' => array(
                        'description' => 'profession du proprietaire du cv.',
                        'type' => 'varchar',
                        'length' => 120,
                        'not null' => TRUE,
                        'default' => '',
                ),

                /*'datenaiss' => array(
                        'description' => 'date de naissance du proprietaire du cv.',
                        'mysql_type' => 'datetime',
                        'not null' => TRUE,
                        'default' => '',
                ),*/

                'fonction' => array(
                        'description' => 'fonction du proprietaire du cv',
                        'type' => 'varchar',
                        'length' => 120,
                        'not null' => TRUE,
                        'default' => '',
                ),

        ),
        'foreign keys' => array(
                'node_cv' => array(
                        'table' => 'node_revision',
                        'columns' => array('cvid' => 'cvid'),
                ),
                'node_author' => array(
                        'table' => 'users',
                        'columns' => array('uid' => 'uid'),
                ),
        ),
        'primary key' => array('infoid'),
);

But I'm getting this error PDOEXCEPTION, and only the cv table is created.
Any suggestions about what I'm doing wrong?
Answer: The problem is that you have two auto-incrementing fields on the second table. Only the primary key should be auto-incrementing:
'infoid' => array(
  'description' => 'clé primaire de la table information.',
  'type' => 'serial',
  'unsigned' => TRUE,
  'not null' => TRUE,
),
'cvid' => array(
  'description' => 'clé primaire de la table cv.',
  'type' => 'serial',
  'unsigned' => TRUE,
  'not null' => TRUE,
),

What you want for cvid is type 'int' not type 'serial'
'cvid' => array(
  'description' => 'clé primaire de la table cv.',
  'type' => 'int',
  'unsigned' => TRUE,
  'not null' => TRUE,
),

That should go through without a PDO exception.
Comment: @user59761 : if this answer really helped you, consider marking it as "accepted" (the green checkmark in front of this answer). For more details, have a look at http://drupal.stackexchange.com/help/someone-answers


$ \forall \epsilon \in \mathbb{R}^{*}_{+} , | x -y | < \epsilon \iff x = y $

Question: Prove that for all  $ \epsilon > 0, \epsilon \in \mathbb{R} $ for every $ x, y \in \mathbb{R} $ if $ | x - y | < \epsilon \iff x = y$
(this question has similar ones in, but this one has the full proof, not only the hint).
Comment: That one don't have the full proof, just the hint.
Answer: $( \Rightarrow ) $ I will prove by contraposition. Our affirmative states that:
$$
\forall \epsilon > 0 \; ( | x - y | < \epsilon ) \implies x = y
$$
The contrapositive is
$$
\lnot ( x = y ) \implies \lnot \forall \epsilon > 0 \; ( | x - y | < \epsilon ) \\
x \neq y  \implies  \exists \epsilon > 0 \; \lnot ( | x - y | < \epsilon ) \\
x \neq y \implies \exists \epsilon > 0 \; ( | x - y | \ge \epsilon )
$$
Therefore, if we prove the contrapositive, we have proved the affirmative. We need to find an $ \epsilon \le | x - y |$.
Let $ \epsilon = \frac{|x-y|}{2} $, since $ x \neq y $, without loss of generality,  let $ x > y $, that implies $ x - y > 0 $, since we have    $ | x - y | = x - y > 0 \implies | x - y | > 0 $.
Therefore $ | x - y | \ge \epsilon = \frac{|x-y|}{2} \implies 2 |x-y| \ge |x-y| $. That is true for all positive values, since we have proved our contraposition our initial hypothesis is valid.
$ ( \Leftarrow ) $ Direct proof. Let $ x = y \implies x - y = 0 \implies | x - y | = | 0 | < \epsilon \;\;\; \square$
Comment: Comments are welcome!


Dynamically moving element position using Javascript

Question: This is the code that's causing me issues:
const moveBlock=()=> {
  let x=myBlock.offsetLeft;
  let y=myBlock.offsetTop;
  keyArray.forEach(key=> {
    if (key==='ArrowRight') {
      myBlock.style.left=`${x+50}px`
    } else if (key==='ArrowLeft') {
      myBlock.style.left=`${x-50}px`
    } else if (key==='ArrowDown') {
      myBlock.style.top=`${y+50}px`
    } else if (key==='ArrowUp') {
      myBlock.style.top=`${y-50}px`
    }
  })
}

I'll briefly explain my program:
The program will start you pressing left, right, up, or down--those commands appear as a list at the top of the document. Then you'll press enter
When enter is pressed, the program goes through the array of keyboard directions and the block moves in the specified direction depending on the command in the array. There's a condition for each arrow direction to move the block 50px which way. This is a sequence so we're supposed to see happening.
However, the block only move 50px right or left, etc only once. Why is that? Am I not iterating my x and y variables correctly?
Answer: You have to calculate the value of x and y again after moving once.
Because when you are moving the block from second time, you are just using original value of x and y computed before the for loop began.
Add this in your forEach() method.
 x = myBlock.offsetLeft;
 y = myBlock.offsetTop;

You have later mentioned in the comments about having a delay between each move.
You can do that by creating another animate block function, having a timeout within a loop and and calling that animate block function in the timeout.
const animateBlock = (key)=> {
    let x = myBlock.offsetLeft;
    let y = myBlock.offsetTop;

    if (key === 'ArrowRight') {
      myBlock.style.left = `${x + 50}px`
    } else if (key === 'ArrowLeft') {
      myBlock.style.left = `${x - 50}px`
    } else if (key === 'ArrowDown') {
      myBlock.style.top = `${y + 50}px`
    } else if (key === 'ArrowUp') {
      myBlock.style.top = `${y - 50}px`
    }
}

const moveBlock = () => {
  keyArray.forEach((key, i) => {
     setTimeout(() => {
       animateBlock(key);
     }, i * 1000);
  })
}

Working demo: https://codepen.io/nikhilmopidevi/pen/gOYjgYd
Comment: @Bob - I could see the block moving, in exact sequence of moves. Did you check out my CodePen: https://codepen.io/nikhilmopidevi/pen/mdbjOBB?
Comment: @Bob - I can clearly see the block moving in bunch of directions in my CodePen: https://codepen.io/nikhilmopidevi/pen/mdbjOBB. Press right arrow thrice and then press enter, you should see the block move three steps to the right. You should also keep in mind that directions get cancelled out, `right` cancels with `left` and  `top` with `bottom`. So, two `right`s and one `left` eventually just moves the block one step to the `right`.
Comment: @Bob - That wasn't clear in your original question. Check out my edited answer and updated CodePen.


Webform Redirect Hook

Question: I built a module that submits the webform data to a soap api. The API an take a while to respond (out of my control), so what I'm looking for is a redirection hook, so I can go Submit->Force Redirection->submit to api.
Users are hitting submit more than once due to the api response time (understandably)
Answer: You can disable the double click  on submit using the below jQuery code.
<code>$('#formid').submit(function(){
    $(this).children('input[type=submit]').prop('disabled', true);
});
</code>
Now you can use the below code to alter submit of webform in your custom module
<code>/**
 * Implementation of hook_form_alter().
 */
function mywebform_extra_form_alter(&$form, &$form_state, $form_id) {
  // Add extra submit for a particular Webform node:
  if ($form_id == 'webform_client_form_44') {

    // Add the submit handler after the existing Webform submit handler,
    // but before the second Webform handler. Pop off the first one and add
    // ours second.
   $form['#submit'][] = 'mywebform_extra_validate_44';
  }
}

/**
 * Submit handler for Webform ID #44.
 */
function mywebform_extra_submit_44(&$form, &$form_state) {
  global $user;

  // Now you can perform here api request and redirect
}
</code>
Hope it will help you.

Webform Redirect Hook


Allow the node preprocess function to be called after setting the theme function in hook_node_view()

Question: In mymodule_node_view(), I set the theme function to be used with the following code.
$node->content['#theme'] = "my_custom_theme_function";

Now the node preprocess function (mymodule_preprocess_node()) is not called anymore.
How do I let Drupal run my node preprocess function, even if I set my theme function to be used?
Answer: With that line, you set the theme function for all the content shown for the node. Your code should be similar to the following one, taken from the documentation for hook_node_view().
function mymodule_node_view($node, $view_mode, $langcode) {
  $node->content['mymodule_field'] = array(
    '#markup' => $additional_field,
    '#weight' => 10,
    '#theme' => 'mymodule_custom',
  );
}

As to why your code is setting the theme function for all the node content, see the code executed by node_view(). (The comments are mine.)
  // This is the function that invokes hook_node_view().
  node_build_content($node, $view_mode, $langcode);

  $build = $node->content;

  // $node->content['#theme'], the value you set, becomes $build['#theme'].

  unset($node->content);

  // The following lines don't set anymore $build['#theme'], since you have already set it.
  // It is similar to executing the following code:
  //   $a = array('first' => "I am the first");
  //   $a += array('first' => "The array will never get this value");
  //
  // If you print the value of $a, you will see it is as it was first set.

  $build += array(
    '#theme' => 'node',
    '#node' => $node,
    '#view_mode' => $view_mode,
    '#language' => $langcode,
  );

  // Now the code is going to use your theme function, which means that not even
  // the node preprocess function is executed.

Normally, what you want to do is adding a new content to the render array for the node. That is what the code I show in the first snippet does.
If you really wanted to change the theme function used for the node, then you should simply implement hook_theme_registry_alter(), and redefine the function associated with the node theme function.
Keep in mind that once you change the used theme function, also the preprocess function changes; in your case, if theme_my_custom_theme_function() is your theme function, then the preprocess function is mymodule_preprocess_my_custom_theme_function().
Comment: This complicates it a bit. I only want to change the theme for one node type, which means to output this node type with a completely custom html (I didn't write it originally, but the change of #theme was inside an `if($node->type=='myspecial')`). And still have a preprocess function called, to load javascript etc. This would normally be done in a theme (like adaptive theme) using a custom tpl.php for a node type, but I need this html defined by a module, independent of the theme. If I change the theme registry, it will change the node theme for all node types.
Comment: The theme function receives three arguments: the node, the view mode, and the language. If the theme should be applied to specific content types, `$node->type` is available.
Comment: So, when I use the theme function (as originally) then the preprocess function is not called. On the other hand, when I use theme_registry_alter, then it applies to all node types (because it's called when clearing cache, not when node is displayed). I need something that applies only for one node type and allows preprocess functions being called (and allows to rewrite the node HTML completely).


Multiple CrudPanel on a single CRUD page in laravel Backpack

Question: In laravel-backpack i want to create custom show page which contain multiple crud page with different styles/formats:
One example : i have Show page for person model and i want to add "Add new Note" option for note model insides of person Show page.
Answer: If I were you, I would create a new Backpack widget and add it to the end of the Show operation.
Alternatively, you can create a custom Operation, and use the ShowOperation as an example.
Comment: I want to create the page with the interface which looks like the interface in attached picture
Comment: if i create custom operation, can i access more than one controller in single operation?


Object tag to transparent mode

Question: A simple question,
How to detect all <object> tag in the dom and add <param name="wmode" value="transparent"> or change its 'wmode' to transparent using jquery.
Thanks in advance.
Answer: jQuery code like this will attempt to change the parameter.
$('object').each(function(index, elem) {
    var wmode = elem.children('param[name="wmode"]');
    if(!wmode.length) {
        elem.append('<param name="wmode" value="transparent"/>');
    } else {
        wmode.attr('wmode', 'transparent');
    }
});

However, this will not achieve the desired effect; you need to completely delete and recreate the object for the change to actually take effect. (I've tried, in the past, temporarily removing and then re-adding the object tag, without cross-browser success.) You may want to look at the SWFObject library. There's even a jQuery plugin for it.
Comment: +1 for noting that this probably isn't going to work in IE. From my past experience, IE will not listen to changes in `object` tags. To get around this, I have tried, with varying success, to remove the `object` element completely and create and insert a new element with your desired properties.

Object tag to transparent mode


Issue with Varnish

Question: We are developing a website with React and Redux. We have just added a Varnish cache on our API and, although everything seems to work well when testing the API on Postman, this is not working fine on our website.
For some reason, all API queries are failing with an 401 status code the first time that they are done, however, they works fine after having failed the first time.
This behaviour has just started happening once we have added Varnish cache, but, we are unable to found the error.
The Varnish configuration file is as follows:
vcl 4.0;

backend default {
    .host = ...;
    .port = ...;
}

sub vcl_backend_response {
    set beresp.ttl = 5m;

    # Don't cache non-200 responses
    if ( beresp.status != 200 ) {
        set beresp.ttl = 0s;
    }
    # Don't cache if "no-cache" or "private" on cache control
    if (beresp.http.cache-control ~ "(no-cache|private)" ||
        beresp.http.pragma ~ "no-cache") {
            set beresp.ttl = 0s;
    }

}

sub vcl_recv {
    # Do not cache Healthcheck call
    if (req.url == "/api/healthcheck") {
        return (pass);
    }

    # Do not cache POST methods
    if (req.method == "POST") {
        return (pass);
    }

    # Do not cache users' calls as each user will be different
    if (req.url ~ "\/api\/v[a-zA-Z0-9\.]+\/users\/.*") {
        return (pass);
    }

    # Ensure that cache is enabled to any call to the API
    if (req.url ~ "/api/*") {
        return (hash);
    }
}

sub vcl_deliver {
  if (req.url ~ "/api/*") {
    set resp.http.Access-Control-Allow-Headers = "Accept, Accept-Encoding, Authorization, Content-Type, Dnt, Origin, User-Agent, X-CSRFToken, X-Requested-With";
    return (deliver);
  }
}

What may be going on?
Thanks a lot
Comment: Based on getting ```401``` which is unauthorised - how do you authenticate API requests? Some header's value / query param / POST data? More details please :)
Comment: The authorization is done through a token send on the header
Answer: I have finally found my issue, there was an return(hash) missing on my configuration file.
The right configuration file is as follows:
vcl 4.0;

backend default {
    .host = ...;
    .port = ...;
}

sub vcl_backend_response {
    set beresp.ttl = 5m;

    # Don't cache non-200 responses
    if ( beresp.status != 200 ) {
        set beresp.ttl = 0s;
    }
    # Don't cache if "no-cache" or "private" on cache control
    if (beresp.http.cache-control ~ "(no-cache|private)" ||
        beresp.http.pragma ~ "no-cache") {
            set beresp.ttl = 0s;
    }

}

sub vcl_recv {
    # Do not cache Healthcheck call
    if (req.url == "/api/healthcheck") {
        return (pass);
    }

    if (req.method != "GET" && req.method != "HEAD") {
        # We only deal with GET and HEAD by default
        return (pass);
    }

    # Do not cache users' calls as each user will be different
    if (req.url ~ "\/api\/v[a-zA-Z0-9\.]+\/users\/.*") {
        return (pass);
    }
    return (hash);
}

sub vcl_deliver {
  if (req.url ~ "/api/*") {
    set resp.http.Access-Control-Allow-Headers = "Accept, Accept-Encoding, Authorization, Content-Type, Dnt, Origin, User-Agent, X-CSRFToken, X-Requested-With";
    return (deliver);
  }
}

Answer: I figure I'd still post for people who apply Varnish to API requests that require authorization of some kind (even you say you solved your problem).
If you happen to require authorization for paths outside \/api\/v[a-zA-Z0-9\.]+\/users\/.* scope, then 401s might still happen because those requests might still be cached.
Furthermore, you can (and should, for performance reasons) cache authenticated requests as well. Simple solution to that and 401 error would be to vary your cache by the token header's value.
Solution 1.
You can change your application code to simply send the extra HTTP header: Vary: X-Token. This is enough to instruct Varnish that cache should be different between different users of your API.
Solution 2.
If you have no way to adjust your app, then some VCL can come to help:
sub vcl_backend_response {
     if (!beresp.http.Vary) { # no Vary at all
        set beresp.http.Vary = "X-Token";
    } elsif (beresp.http.Vary !~ "X-Token") { # add to existing Vary
        set beresp.http.Vary = beresp.http.Vary + ", X-Token";
    }
    ...
}

P.S. it is generally not recommended to put "trailing" return in vcl_recv to ensure that the builtin vcl_recv routines would still run.

Issue with Varnish


O que é um daemon?

Question: Sei que "demônio" vêm do latim daemon, mas acredito que essa palavra tem outro significado no meio tecnológico.
O que é um daemon? O que come? Para que serve?
Answer: Etimologia da palavra daemon:
Em um documento da Virginia Tech/Norfolk State University intitulado The Origin of the word Daemon se encontra a explicação para a origem da palavra "daemon":

Escrevo uma coluna de curiosidades para um jornal chamado The Austin
Chronicle. Alguém me perguntou a origem da palavra daemon no que se
refere à computação. O melhor que posso dizer com base em minha
pesquisa é que a palavra foi usada pela primeira vez por pessoas de
sua equipe no Projeto MAC usando o IBM 7094 em 1963. O primeiro daemon
(uma abreviação de Disk And Executive MONitor) era um programa que
fazia backups em fita automaticamente o sistema de arquivos.
Richard Steinberg do jornal The Austin Chronicle

Sua explicação sobre a origem da palavra daemon está correta, pois meu
grupo começou a usar o termo por volta desse período. No entanto, a
explicação da sigla é nova para mim. Nosso uso da palavra daemon foi
inspirado no daemon da física e da termodinâmica de Maxwell. (Minha
formação é física). O daemon de Maxwell era um agente imaginário que
ajudava a classificar moléculas de diferentes velocidades e trabalhava
incansavelmente em segundo plano. Fantasiosamente, começamos a usar a
palavra daemon para descrever processos em segundo plano que
trabalhavam incansavelmente para realizar tarefas do sistema.
Encontrei uma explicação muito boa sobre tudo isso online em:
http://www.takeourword.com/TOW129/page2.html (Pesquise em "Maxwell"
para localizar o parágrafo pertinente.)
Fernando J. Corbato engenheiro do projeto MAC

[Aviso: este parágrafo é sobre ciência, portanto, se este tópico lhe
causar um alarme indevido, feche os olhos até terminar de lê-lo.] O
cientista do século 19 James Maxwell uma vez sonhou acordado (o termo
educado é "experimento mental") sobre um problema de física. Ele
imaginou um recipiente fechado dividido ao meio. No meio da divisória
havia um pequeno portão, grande o suficiente apenas para admitir uma
molécula de gás. Este portão, na imaginação de Maxwell, era operado
por um pequeno daemon. Este daemon observou a velocidade (isto é,
temperatura) das moléculas que se dirigiam para o portão e, dependendo
da velocidade, as deixou passar. Se ele deixasse apenas as moléculas
lentas passarem do lado A para o lado B e apenas as moléculas rápidas
passassem do lado B para o lado A, então A ficaria quente enquanto B
esfriava.  O daemon de Maxwell era apenas imaginário, é claro, mas
como parecia escapar das leis da termodinâmica, causou um grande
rebuliço. No final das contas, porém, a teoria da mecânica quântica
mostrou por que ela não funcionaria. [OK, você pode abrir os olhos,
agora.]
Como você provavelmente sabe, os "processos do sistema" chamados
daemons monitoram outras tarefas e executam ações predeterminadas
dependendo de seu comportamento. Isso lembra tanto o daemon de Maxwell
observando suas moléculas que só podemos presumir que quem quer que
tenha apelidado esses "processos do sistema" tinha o daemon de Maxwell
em mente. Nossa suposição foi confirmada para nós diretamente pelos
professores Corbato e Saltzer, que trabalharam em um projeto de
desenvolvimento de sistema no MIT em 1963 conhecido como Projeto MAC.
Eles e os membros de sua equipe usaram o daemon pela primeira vez
neste sentido naquela época, baseando-se no daemon de Maxwell.
Paragrafo do www.takeourword.com citado acima por Fernando J. Corbato.

Descrição:
Da Wikpédia:
Em sistemas operacionais multitarefa, um daemon é um programa de computador que executa como um processo em plano de fundo, em vez de estar sob o controle direto de um usuário interativo. Tradicionalmente, o nome de processo de um daemon termina com a letra d, para deixar claro que o processo é, de fato, um daemon, e para diferenciação entre um daemon e um programa de computador normal. Por exemplo, syslogd é o daemon que implementa o recurso de logging do sistema e sshd é um daemon que serve conexões SSH de entrada.
Do linux man-pages:
Um daemon é um processo de serviço executado em segundo plano e supervisiona o sistema ou fornece funcionalidade a outros processos. Tradicionalmente, os daemons são implementados seguindo um esquema originado em SysV Unix.     Daemons modernos devem seguir um esquema mais simples, porém mais poderoso(aqui chamado de daemons modernos), conforme implementado pelo systemd.
Inicialização:
SysV Daemons(estilo antigo): (Extraido do linux man-pages)
Quando um daemon SysV tradicional é iniciado, ele deve executar o as etapas a seguir como parte da inicialização. Observe que estas etapas são desnecessárias para daemons de novo estilo (veja abaixo), e só deve ser implementado se a compatibilidade com SysV for     essencial.

Fecha todos os descritores de arquivo abertos, exceto a entrada padrão, saída e erro (ou seja, os três primeiros descritores de arquivo 0, 1, 2). Isso garante que nenhum o descritor de arquivo seja passado acidentalmente para o processo do daemon. No Linux, este é melhor implementado iterando por meio de /proc/self/fd, com um fallback da iteração do descritor de arquivo 3 para o valor retornado por getrlimit() para RLIMIT_NOFILE.

Redefine todos os manipuladores de sinais para seus padrões. Isso é melhor feito iterando através dos sinais disponíveis até o limite de NSIG e redefinindo-os para SIG_DFL.

Reinicializa a máscara de sinal usando sigprocmask().

Higieniza o ambiente, removendo ou redefinindo variáveis de ambiente que podem impactar negativamente o daemon tempo de execução.

Chama fork() para criar um processo em segundo plano.

No processo filho, chama setsid() para separar de qualquer terminal e criar uma sessão independente.

No processo filho, chama fork() novamente, para garantir que o daemon nunca podssa readquirir um terminal novamente. (Isso é relevante se o programa,e todas as suas dependências, não cuidadosamente especifique O_NOCTTY em cada chamada open() que pode potencialmente abrir um nó de dispositivo TTY.)

Chama exit() no primeiro filho, de modo que apenas o segundo filho (o processo daemon real) permanece. Isso garante que o processo daemon é redirecionado para init/PID1, como todos daemons deveriam ser.

No processo daemon, conecta a `/dev/null' à entrada padrão, saída e erro.

No processo daemon, redefine o umask para 0, para que o arquivo modos passados para open(), mkdir() e similares controlem diretamente o modo de acesso dos arquivos e diretórios criados.

No processo daemon, altera o diretório atual para o diretório raiz (/), a fim de evitar que o daemon impeça que os pontos de montagem sejam desmontados involuntariamente.

No processo do daemon, escreve o PID do daemon (conforme retornado por getpid()) para um arquivo PID, por exemplo /run/foobar.pid(para um  daemon hipotético "foobar") para garantir que o daemon não possa ser iniciado mais de uma vez. Isso deve ser implementado em maneira livre de condições de corrida, de modo que o arquivo PID só é atualizado quando é verificado ao mesmo tempo que o PID previamente armazenado no arquivo PID não exista mais ou pertenç a um processo estrangeiro.

No processo daemon, cancela os privilégios possível e aplicável.

A partir do processo daemon, notifica o processo original iniciado que a inicialização está completa. Isso pode ser implementado via um pipe anônimo ou canal de comunicação similar que é criado antes do primeiro fork() e, portanto, disponível em ambos processos, o original e daemon.

Chame exit() no processo original. O processo que invocou o daemon deve ser capaz de assegurar que este exit() aconteça após a inicialização ser concluída e todos os canais de comunicação foram estabelecidos e estão acessíveis.

Daemons modernos: (Extraido do linux man-pages)
Serviços modernos para Linux devem ser implementados como um novo estilo de daemons. Isso torna mais fácil supervisioná-los e controlá-los em tempo de execução e simplifica sua implementação.
Para desenvolver um daemon de novo estilo, nenhuma das etapas de inicialização das etapas recomendadas para daemons SysV precisam ser implementadas. Os novos sistemas de inicialização como o systemd tornam todos eles redundante. Além disso, uma vez que algumas dessas etapas interferem com monitoramento de processo, passagem de descritor de arquivo e outras funcionalidade do sistema de inicialização, é recomendado não os executar quando rodando com um serviço moderno.
Observe que os sistemas de inicialização modernos garantem a execução de processos daemon em um contexto de processo limpo, que é garantir que o ambiente é higienizado, que os manipuladores de sinal e máscara sejam redefinido e nenhuma sobra de descritor de arquivo restante seja passada.
Daemons serão executados em sua própria sessão, com entrada padrão conectada a /dev/null e  saida/erro padrão and standard output/error connected /dev/null e saída padrão / erro conectada ao serviço de registro systemd-journald.service(), a menos que configurada de outra forma. O umask é redefinido.
É recomendado para daemons de modernos implementar o que se segue:

Se SIGTERM for recebido, encerre o daemon e saia de forma limpa.

Se SIGHUP for recebido, recarregue os arquivos de configuração, se isto se aplicar.

Forneça um código de saída correto do processo daemon principal, como isso é usado pelo sistema init para detectar erros de serviço e problemas. Recomenda-se seguir o esquema de código de saída como definido nas recomendações LSB para scripts de inicialização SysV.

Se possível e aplicável, exponha a interface de controle do daemon através do sistema IPC D-Bus e pegue um nome de barramento como última etapa da inicialização.

Para integração no systemd, forneça um arquivo de unidade a.service que           carrega informações sobre como iniciar, parar e utilizar o daemon. Veja systemd.service para detalhes.

Tanto quanto possível, conte com a funcionalidade do sistema de inicialização           para limitar o acesso do daemon a arquivos, serviços e outros recursos, ou seja no caso do systemd, que dependem de controle de limite de recursos do systemd em vez de implementar seu próprio, conte com o privilégio de descartar o código do systemd em vez de implementá-lo no daemon e semelhantes. Ver systemd.exec() para os controles disponíveis.

Se o D-Bus for usado, torne seu daemon ativável por barramento fornecendo um arquivo de configuração de ativação do serviço D-Bus. Esta abordagem tem várias vantagens: seu daemon pode ter inicialização adiada.
Sob demanda pode ser iniciado em paralelo com outros daemons o que maximiza a paralelização e a velocidade do boot.
Rapidez, seu daemon pode ser reiniciado em caso de falha sem perder quaisquer solicitações do barramento, pois o barramento enfileira solicitações para serviços ativáveis.

Se o seu daemon fornecer serviços para outros processos locais ou clientes remotos através de um soket, deve ser feito como socket-ativável seguindo o esquema indicado abaixo.
Como a ativação do D-Bus, isso permite o início sob demanda de serviços, bem como permite melhor paralelização de inicialização do serviço. Além disso, para protocolos sem estado (como syslog, DNS), um daemon que implementa ativação baseada em soket pode ser reiniciado sem perder uma única solicitação.

Se aplicável, um daemon deve notificar o sistema de inicialização sobre conclusão da inicialização ou atualizações de status via interface sd_notify(3).

Em vez de usar a chamada syslog() para registrar diretamente no serviço de syslog do sistema, um daemon moderno pode escolher simplesmente registrar o erro padrão via fprintf(), que é então é encaminhado ao syslog pelo sistema de inicialização. Se os níveis de registro forem necessário, eles podem ser codificados prefixando log individual           linhas com strings como "<4>"(para log de nível 4 "AVISO" em esquema de prioridade do syslog), seguindo um estilo semelhante a chamada do Kernel Linux printk() a nivel de sistema. Para detalhes, veja sd-daemon() e systemd.exec().

Como daemons modernos são chamados sem um TTY de controle(mas como seus próprios encabeçadores de sessão) deve-se tomar cuidado para sempre especifique O_NOCTTY em chamadas open() que possivelmente referenciar um nó de dispositivo TTY, de modo que nenhum TTY de controle seja adquirido acidentalmente.

As recomendações são similares mas não idênticas aos Requisitos Apple MacOS x Daemon.
Noutros sistemas operacionais:
Microsoft DOS TSR: Trecho da Wikpédia
Um programa terminate-and-stay-resident(geralmente TSR) é um programa de computador executado no DOS que usa uma chamada de sistema para retornar o controle ao DOS como se tivesse terminado, mas permanece na memória do computador para que possa ser reativado posteriormente. Essa técnica superou parcialmente a limitação do DOS de executar apenas um programa ou tarefa por vez. Os TSRs são usados apenas no DOS, não no Windows.
Embora muito úteis, ou mesmo essenciais para superar as limitações do DOS , os TSRs têm a reputação de criadores de problemas. Muitos sequestram o sistema operacional de várias maneiras documentadas ou não documentadas, muitas vezes fazendo com que os sistemas travem na ativação ou desativação quando usados com aplicativos específicos ou outros TSRs. Alguns vírus e outros malwares foram codificados como TSRs e são deliberadamente problemáticos. Além disso, no DOS todos os programas, mesmo aqueles com grande quantidade de RAM física , devem ser carregados nos primeiros 640  KB de RAM (a memória convencional) e os TSRs não são exceção e pegam pedaços desses 640 KB que, portanto, não estão disponíveis para outros aplicativos.
Microsoft Windows Services: (Trecho da Wikpedia)
Nos sistemas operacionais Windows NT, um Windows Service(Ou Serviço Windows) é um programa de computador que opera em segundo plano. É semelhante em conceito a um daemon Unix.
Um serviço do Windows deve estar em conformidade com as regras de interface e protocolos do Service Control Manager, o componente responsável por gerenciar os serviços do Windows. É o aplicativo Services and Controller, services.exe, que lança todos os serviços e gerencia suas ações, como iniciar, terminar, etc.
Os serviços do Windows podem ser configurados para iniciar quando o sistema operacional for iniciado e rodar em segundo plano enquanto o Windows estiver em execução. Alternativamente, eles podem ser iniciados manualmente ou por um evento.
Os sistemas operacionais Windows NT incluem vários serviços executados no contexto de três contas de usuário: Sistema, Serviço de Rede e Serviço Local. Esses componentes do Windows são frequentemente associados ao Processo de Host para Serviços do Windows.
Como os serviços do Windows operam no contexto de suas próprias contas de usuário dedicadas, eles podem operar quando um usuário não está conectado.
Antes do Windows Vista , os serviços instalados como um "serviço interativo" podiam interagir com a área de trabalho do Windows e mostrar uma interface gráfica do usuário . No Windows Vista, entretanto, os serviços interativos estão obsoletos e podem não funcionar corretamente, como resultado da proteção do Windows Service.
Answer: Daemon é um processo que roda no background de um sistema operacional. Basicamente, ele fica esperando requisições que serão feitas ao sistema, através do usuário, e trata dessas requisições para que elas possam ser atendidas. Ele atende não só requisições vindas do usuário, mas também dos mais diversos processos que precisam ficar rodando o tempo inteiro no background do sistema também, como indexamento de arquivos, atualizações de software, compressão de dados, web server,ssh server, dentre vários outros serviços.
Answer: É o equivalente a um "serviço" do Windows, um programa que roda em segundo plano.
Entrando um pouco nos detalhes técnicos, um daemon
a) possui PGID (grupo de processos) exclusivo, só seu
b) possui SID (session id, uma espécie de grupo de grupos de processos) exclusivo só seu
c) não há um terminal controlador ligado a ele
Tudo isso para que o processo rode da forma mais isolada e previsível possível, sem que seu comportamento seja influenciado pelo que acontece no resto da máquina.
Quando um daemon é iniciado, é recomendado executar uma sequência de comandos para que, além do PGID e SID, o processo "esqueça" também outros parâmetros (umask, chdir) que ele de outra forma poderia herdar do processo-pai original : http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html

O que é um daemon?


Best Practice - Node Template Logic

Question: I have a node template file that requires a lot of logic. So much so that in order to make things easier I have created functions inside my custom node.tpl file. What is best practice for separating logic from the node.tpl?
Thanks!
Answer: You should use the template_preprocess_node() function. Add this to your template.php in your theme and do whatever you have to do.

Best Practice - Node Template Logic


How to solve following auto-layout constrains problems?

Question: I am using auto-layout inside my app and I can't manage to make constrains ok. I will need some help (kinda new to auto-layout)
My views and constrains:

Current result on iPhone 6 plus (smaller screen does not show nothing):

Expected result:
It should make views smaller and at the same time make space between views smaller like this one:

How can i manage that?
Thank you!
Comment: Have you tried making a width constraint?  Add a width constraint that is >= whatever the minimum width you would accept.  Add that width to all views and make all have equal widths
Comment: This might be a little advanced since you are new at auto layout, but you can add IBOutlet's to constraints.  ex (NSLayoutContraint*width;)  so if you add constraints to the spaces between each view then programmatically figure out what size that needs to be, you can set the width between all views so that they fit.
Comment: tried for one view (and they all have equal width one with each other) now but views won't fit inside screen and size between them is same ( big ) ..it will show like 6 views
Comment: Thank you for your help. Check out my answer to see how I've done it. Thanks again!
Comment: Seems like that won't give you the same results on each device.  Glad I could help though!
Comment: It does. I have no explanation for this... Edited answer
Answer: Okay, found out the answer and it's kinda awkward but I was struggling for finding him and maybe it will help someone.
I solved by making views bigger:

And the result on iPhone 6+:

And on iPhone 4s:


Detecting changes in distribution of multiple variables

Question: I am a bit new to this field. So I needed help in finding out which topic should I focus on for achieving this.
Suppose I have N dependent random variables. I have n samples of each of these random variables.
Now I want to check if the kth sample follows the pattern that is suggested by the previous (k-1) samples.
For example if there are 2 variables - X1 and X2. For the first 10 samples lets say X1 > X2. But if for the next sample X1 < X2, then this sample is anomalous. I need to detect such an anomalous sample.
Can you tell me what statistical machine learning concepts should I study in order to understand which techniques are applicable in such a scenario?
From my limited knowledge this appears to be a classification problem that must be attacked with unsupervised technique.
Comment: I find the question too vague. You need to define "anomalous", e.g. as you did in the example. In statistics terms, you need to define a model for "normality" (i.e. lack of abnormality)...
Answer: This sounds like a job for the Mahalanobis Distance. You would apply this by estimating the population covariance and mean vector using the previous $(k-1)$ samples (assuming $k > N$, where $N$ is the dimension of your observed vectors), and then computing the Mahalanobis Distance. A google search reveals a lot of hits on this topic, Bartkowiak seems like a decent starting place.
Comment: I get a _very_ small number when I look at the `rcond(cov(mat1))` using your example `mat1`, like 1e-17. Your covariance is rank 5, so any techniques which invert it are going to fail. Looking at `rowSums(mat1)` I see the problem: the columns of `mat1` are _not_ linearly independent--they all sum to 10000. This is probably due to how your Hypergeometric generation process works (_i.e._ each ball drawn has to be from _some_ class). To get around this problem, subselect the first five columns of `mat1` and ignore the last one (it is completely determined by the first five). hth.
Comment: I tried calculating with a contrived dataset having 100 samples drawn from a hypergeometric distribution. The dimension was 6. I get the following error in R:

> mahalanobis(x=c(28, 22, 3, 20, 4, 2), mean1, cov1)
Error in solve.default(cov, ...) :
  system is computationally singular: reciprocal condition number = 2.16688e-018
Comment: It works for me: `mean1 <- c(0,0,2,3,4,1)
cov1 <- cov(matrix(rnorm(200*6),ncol=6))
mahalanobis(c(28,22,3,20,4,2),center=mean1,cov=cov1)`
Maybe your covariance _is_ singular? check with `rcond(cov1)` (should give a reasonably small number)
Comment: yes it does give a small number.
Comment: mat1 = t(rMWNCHypergeo(100, m=c(10000000, 10000000, 10000000, 10000000, 10000000, 10000000),  n=10000, odds=c(30, 20, 10, 30, 5, 5)));
cov1 = cov(mat1);
mean1 = c(mean(mat1[,1]), mean(mat1[,2]), mean(mat1[,3]), mean(mat1[,4]), mean(mat1[,5]), mean(mat1[,6]));

I used Hypergeometric distribution. What should we do when the cov matrix is singular?
Comment: This does seem to work. I tried giving points which were approximately similar to the ones in the dataset. I get a low value for this distance. Anything unusual causes this to shoot up. I have  a few questions though:
1. This measure seems to be somewhat dated. Have better techniques been since then? I can imagine updating the covariance matrix, mean as each sample comes in and flagging the sample as anomalous when the distance is too higher than a threshold.
Comment: 2. Can this or some other technique be modified to point out the defaulting variable? It is possible that there is only one variable that is causing the imbalance. I am thinking on the lines of mainting marginal mean, covariance matrices as in mean, covariance matrix of $ 5 \choose 4 $ combinations of variables. Is that the correct way?
Answer: This sounds to me more like a change point problem. You should investigate the bcp package, http://cran.r-project.org/web/packages/bcp/index.html, as well as strucchange, http://cran.r-project.org/web/packages/strucchange/index.html
John Emerson maintains the bcp package, and when I met him, he seemed very willing to engage the community and potential users: john.emerson at yale.edu
Alternatively, if your data are time series data, you may wish to investigate the qcc package, and read some of Douglas Montgomery's work on Statistical Quality Control.


Puppetserver not coming up after fresh installation

Question: Pupppetserver service is not coming up after fresh installation. It is showing the following error
 Exception in thread "main" java.lang.ClassNotFoundException: java.nio.file.Files, compiling:(puppetlabs/puppetserver/certificate_authority.clj:1:1)
    at clojure.lang.Compiler.load(Compiler.java:7391)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
......
......
    at clojure.main.main(main.java:37)
 Caused by: java.lang.ClassNotFoundException: java.nio.file.Files

The system has 2G of memory. I changed the memory settings to 1G from 2G , but the service is still not coming up.
  JAVA_ARGS="-Xms1g -Xmx1g -XX:MaxPermSize=256m"

  $ cat /etc/redhat-release
  CentOS release 6.7 (Final)

  $ rpm -q puppetserver
   puppetserver-2.7.2-1.el6.noarch

Please suggest.
Comment: Which version of Java? Perhaps it's older (e.g. 1.6 rather than 1.7).
Comment: The puppetserver package appears to depend on java-1.8, so try checking `alternatives` (i.e. /usr/bin/java) is using the 1.8 installation.
Comment: Yeah.....  $ rpm -qf /usr/java/jdk1.6.0_45/bin/java
               jdk-1.6.0_45-fcs.x86_64
Answer: It looks like you are trying to run the puppetmaster using Java 6, and it needs a more recent version. Install a newer version of java ( yum install java-1.8.0-openjdk-headless ) and try again.
Comment: (java.nio.file.Files was new in java 7)


Rate the parameter and examine the centeredness of that parameter

Question: Distribution $X$ is described with density function
$$  f(x) =
\begin{cases}
\frac{\alpha}{c}(\frac{c}{x})^{\alpha +1},  & x>c \\
0, & x\le c
\end{cases}$$ where $\alpha >0$. Based on a sample of perimeter $n$, evaluate parameter $\alpha$. Examine the centeredness of that parameter.
Evaluation of parameter $\alpha $ gives $${\alpha}=\frac{n}{-n\ln c+\sum_{i=1}^n \ln\frac{x_i}{c}}$$
I am stuck with examining the centeredness of that parameter.
Evaluation of a parameter is centered if $E(\alpha)=\alpha$, else it is not.
We have:
$$E(\alpha)=E\left(\frac{n}{-n\ln c+\sum_{i=1}^n \ln\frac{x_i}{c}}\right)=nE\left(\frac{1}{-n\ln c+\sum_{i=1}^n \ln\frac{x_i}{c}}\right)$$
$$=n\int_{-\infty}^{+\infty}\frac{1}{y}f_Y(y)dy$$ where $Y=-n\ln c+\sum_{i=1}^n \ln\frac{x_i}{c}$
Let $$Z_i=\ln\frac{X_i}{c}$$
Question: How to evaluate $f_{Z_i}(z)$?
Than, from $f_{Z_i}(z)$ we have $f_{Y}(y)$, and finally, $E(\alpha)$.
Answer: CDF of $Z_i$ equals to
$$
F_{Z_i}(z)=\mathbb P(Z_i\leq z)=\mathbb P\left(\ln \frac{X_i}{c}<z\right)=\mathbb P\left(X_i<ce^z\right)=F_{X_i}(ce^z) \text{ for } z>0.
$$
Find derivative to get PDF:
$$
f_{Z_i}(z)=\left(F_{Z_i}(z)\right)'=ce^zf_{X_i}(ce^z)=\begin{cases}
\alpha e^{-\alpha z},  & z>0 \\
0, & z\le 0
\end{cases}
$$
This is exponential distribution.
Also check the estimator of $\alpha$: it should be
$$
\hat{\alpha}=\frac{n}{\sum_{i=1}^n \ln\frac{x_i}{c}}=\frac{n}{-n\ln c+\sum_{i=1}^n \ln x_i}
$$
Note also that the sum $\sum_{i=1}^n Z_i$ in denominator has Gamma distribution.


ansible double loops execute one by one based on when condition

Question: In ansible variables are getting dynamically from register output
first loop will collect the values from registered ouput result and once it will satisfy the when condition, next loop should start the execution.
how to use two loops in one when condition in ansible
- name: stop the http service
 command: sh http.sh stop {{item}}
 args:
   chdir: /opt/http/
 loop: "{{http.stdout_lines}}"
 when: "item.stdout != 0"
 loop: "{{wordcount.results}}"

this is the code
but i unable to use two loops continuous
if one loop complete it should run next loop
Answer: Sorry, but it will not work the way you want it to. You can only define the loop once per task; the second definition will be ignored. You might need to break this into multiple tasks, however, I can't propose a solution because its not entirely clear from your example on what you are trying to accomplish. More context might help.


Use custom SCSS with Bootstrap-Vue + Webpack + Vue.js

Question: I'm creating an application using VueJS with Bootstrap-Vue. I am trying to import SCSS file to override the Bootstrap variables as well as another SCSS for custom styles.
Here is what I have so far:

Installed node-sass, sass-loader and css-loader

npm install node-sass sass-loader css-loader --save-dev

Added the following to build/webpack.base.conf.js

{ test:/\.(s*)css$/, use:['style-loader','css-loader', 'sass-loader']}

Created a SCSS file in src/assets/scss/app.scss

main.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
import App from './App'
import router from './router'
import fontawesome from '@fortawesome/fontawesome'
import light from '@fortawesome/fontawesome-pro-light'

Vue.use(BootstrapVue)

Vue.config.productionTip = false

fontawesome.library.add(light)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

When I run npm run dev I get the following error:
ERROR  Failed to compile with 1 errors                                                      21:05:54

 error  in ./src/main.js

Syntax Error: Unexpected token, expected ; (29:7)

  27 | })
  28 |
> 29 |
  32 |

 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js

    fontawesome.library.add(light)

    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      components: { App },
      template: '<App/>'
    })

I am not sure why it is not working. I have tried various solutions on Github and Stack Overflow.
Any help would be appreciated.
Comment: Your file is a file.js and you need to use Single file component to be able to use scss as you intended to. You need to convert your file to file.vue instead then you would be able to use
Answer: You can't write style tag in javascript like this. You need to either move it to a vue file and attach a loader to it, or use a standard import:
import './assets/scss/app.scss';

Without the style tags or the @ symbol.
Comment: I also had to remove `{ test:/\.(s*)css$/, use:['style-loader','css-loader', 'sass-loader']}` from build/webpack.base.conf.js.
Comment: I added file assets/scss/app.scss and I get ERROR "This relative module was not found: ./assets/scss/app.scss in ./src/main.js"
Comment: @Cichy Not much information to go on there, I don't know what your directory structure looks like.


Where does $(\tan x)^{\sin x}=(\cot x)^{\cos x}$?

Question: So I was yet again searching throughout the homepage of Youtube to see if there were any math equations that I thought that I might be able to solve when I came across this video by SyberMath that asked the question:
$$\text{Solve: }~~~(\tan x)^{\sin x}=(\cot x)^{\cos x}$$
Which I thought that I might be able to solve. Here is my attempt at solving it:

$$(\tan x)^{\sin x}=(\cot x)^{\cos x}$$

$$\sin(x)\ln(\tan x)=\cos(x)\ln(\cot x)$$

$$\tan(x)\ln(\tan x)=\ln(\cot x)~~~~~~~\text{ (since }\frac{\sin(x)}{\cos(x)}=\tan(x)\text{)}$$

$$\text{Therefore, we need to find where }(\tan x)^{\tan x}\text{ is equal to }\cot(x)$$

$$\text{And solving for }x\text{ will get us that }x=\frac{\pi}{4}+\pi n,n\in\mathbb{Z}\text{, (}\mathbb{Z}\text{ being the set of integers)}$$

And, plugging this into Desmos we see that we are correct!

$$\mathbf{\text{My question}}$$

Is my solution correct, or is there anything that I could do to attain the correct solution more easily?
Comment: $(tanx)^{(sinx+cosx)} =1$ implies that either $tanx=1$ or $sinx+cosx=0$
Comment: Be careful: the equation becomes meaningless if $\tan x \le 0$. Under that assumption you can argue as @ShlokJain comment suggests, and the fact that $\sin x$ and $\cos x$ must have the same sign, you can discard the condition $\sin x + \cos x =0$. This means that the equation is equivalent to $\tan x =1$.
Comment: @Crostul So the equation could only be possibly true if $x=\frac{\pi}{4}+\pi n,n\in\mathbb{Z}$?
Comment: At $(\tan x) (\ln \tan x) = \ln \cot x$ note that $\cot x = (\tan x)^{-1}$ and $\ln \cot x = -\ln\tan x.$   So, $(\tan x)(\ln\tan x) = -\ln \tan x.$  Either, $\tan x = -1$ or $\ln \tan x = 0$
Answer: $(\tan x)^{\sin x}=(\cot x)^{\cos x}$ and $\cot x=\frac{1}{\tan x}$, we get
$$(\tan x)^{\sin x}=(\tan x)^{-\cos x}\Rightarrow (\tan x)^{\sin x+\cos x}=1$$
Case.(1) $$\tan x=1\Rightarrow x=\frac{\pi}4+n\pi, ~~n\in \mathbb{Z}$$
Case.(2)$$\sin x+\cos x=0\Rightarrow \sin\left(x+\frac{\pi}4\right)=0\Rightarrow x=-\frac{\pi}4+n\pi, ~~n\in \mathbb{Z}$$
The solution is:
$$ x=\pm\frac{\pi}4+n\pi, ~~n\in \mathbb{Z}$$
Comment: Just an observation that the answer can be written as $x=\frac{\pi}{4}+\frac{\pi}{2}n=\frac{\pi}{4}(2n+1)$
Answer: For the sake of brevity, let $s = \sin x$ and $c = \cos x$.  Then $\tan x = \frac{s}{c}$ and $\cot x = \frac{c}{s}$, so:
$$(\frac{s}{c})^s=(\frac{c}{s})^{c}$$
Taking the logarithm of each side gives:
$$s(\ln s - \ln c)=c(\ln c - \ln s)$$
Which can be rearranged to:
$$(s + c)(\ln s - \ln c) = 0$$
If $s + c = 0$, i.e., $\sin x + \cos x = 0$, then $x \in \{ \frac{3\pi}{4}, \frac{7\pi}{4} \} + 2\pi n, n\in\mathbb{Z}$.
If $\ln s - \ln c = 0$, then $\sin x = \cos x$, so $x \in \{ \frac{\pi}{4}, \frac{5\pi}{4} \} + 2\pi n, n\in\mathbb{Z}$.
Combining these cases gives $x \in \{ \frac{\pi}{4}, \frac{3\pi}{4}, \frac{5\pi}{4}, \frac{7\pi}{4} \} + 2\pi n, n\in\mathbb{Z}$.
In other words, $x$ can be any odd multiple of $\frac{\pi}{4}$.
$$\boxed{x = \frac{\pi}{4}(2n+1), n \in \mathbb{Z}}$$
Comment: Great answer! I think that the two answers here are the only ways we can actually solve this problem.
Answer: As a variant of the method given by Dan, again letting $s = \sin x, c = \cos x$, we have:
$$\left( \frac s c \right)^s = \left( \frac c s \right)^c \iff \frac{s^s}{c^s} = \frac{c^c}{s^c} \iff s^{s+c} = c^{s+c}$$
Rather than taking the logarithm, we've simply cross-multiplied. $a^n = b^n \iff a=b \lor n=0$. (That is, this is true when the base is the same on both sides, or when both exponentials are $1$.) This corresponds to $\sin x = \pm \cos x$, which is true at all odd multiples of $\tau/8$, as shown by others.
Comment: Ah, I see you're a Tauist.


error when encoutering some data, but some are correct

Question: so i make a waging program using python, with that waging program I have an excel data that I need to processed.
my program as such
<code> # Install required library
!pip install xlrd
import pandas as pd
from datetime import time, timedelta
import openpyxl
import math
import numpy as np

# Mount google drive
from google.colab import drive
drive.mount('/content/drive')

# Read the Excel file
path = '/content/drive/MyDrive/Colab Notebooks/Book1.xlsx'
df = pd.read_excel(path)

# Convert the 'Tgl/Waktu' column to datetime format
df['Tgl/Waktu'] = pd.to_datetime(df['Tgl/Waktu'])

# Extract the date and time from the 'Tgl/Waktu' column
df['Date'] = df['Tgl/Waktu'].dt.date
df['Time'] = df['Tgl/Waktu'].dt.time

# Group the data by employee name and date
grouped_df = df.groupby(['Nama', 'Date'])

# Set the overtime threshold to 16:30:00
overtime_threshold = time(hour=16, minute=30)

# Set the late limit
late_limit = time(hour=8, minute=15)

# Set holidays date
holidays_date = ['2023-1-1', '2023-1-22', '2023-2-18', '2023-3-22', '2023-4-7', '2023-4-22', '2023-4-23', '2023-5-1', '2023-5-18', '2023-6-1', '2023-6-4','2023-6-29',
                '2023-7-19', '2023-8-17', '2023-9-28', '2023-12-25', '2023-1-23', '2023-3-23', '2023-4-21', '2023-4-24', '2023-4-25', '2023-4-26', '2023-6-2', '2023-12-26',
                '2023-1-8', '2023-1-15', '2023-1-29', '2023-2-5', '2023-2-12', '2023-2-19', '2023-2-26', '2023-3-5', '2023-3-12', '2023-3-19', '2023-3-26', '2023-4-2',
                '2023-4-9', '2023-4-16', '2023-4-23', '2023-4-30', '2023-5-7', '2023-5-14', '2023-5-21', '2023-5-28', '2023-6-11', '2023-6-18', '2023-6-25',
                '2023-7-2', '2023-7-9', '2023-7-16', '2023-7-23', '2023-7-30', '2023-8-6', '2023-8-13', '2023-8-20', '2023-8-27', '2023-9-3', '2023-9-10', '2023-9-17',
                '2023-9-24', '2023-10-1', '2023-10-8', '2023-10-15', '2023-10-22', '2023-10-29', '2023-11-5', '2023-11-12', '2023-11-19', '2023-11-26', '2023-12-3', '2023-12-10',
                '2023-12-17', '2023-12-24', '2023-12-31','2022-12-20']

# Iterate over the grouped data
for (name, date), group in grouped_df:
    # Calculate the total work hours and overtime hours for each employee on each day
    start_time = group['Time'].min()
    end_time = group['Time'].max()
    total_hours = (timedelta(hours=end_time.hour, minutes=end_time.minute, seconds=end_time.second) -
                   timedelta(hours=start_time.hour, minutes=start_time.minute, seconds=start_time.second)).total_seconds() / 3600
    if total_hours > 8:
        hours_worked = 8
        if end_time > overtime_threshold:
          overtime_hours += (end_time - overtime_threshold).total_seconds() / 3600
    elif total_hours < 8:
        if start_time > late_limit:
            hours_worked = 5
        else:
            hours_worked = total_hours
            hours_worked = math.floor(total_hours)  # Round down the hours_worked value
            overtime_hours = 0
    if end_time > overtime_threshold:
        overtime_hours += (end_time - overtime_threshold).total_seconds() / 3600

    # Calculate the payment for each employee on each day
    if hours_worked == 8:
        if overtime_hours > 0:
            if name == 'Alif':
                payment_each_date = 60000 + overtime_hours * 10000
            elif name == 'budi':
                payment_each_date = 70000 + overtime_hours * 10000
            elif name == 'adi':
                payment_each_date = 60000 + overtime_hours * 10000
            elif name == 'supriyanto':
                payment_each_date = 70000 + overtime_hours * 10000
            elif name == 'Edi':
                payment_each_date = 60000 + overtime_hours * 10000
            elif name == 'Tri Gunawan':
                payment_each_date = 60000 + overtime_hours * 10000
            elif name == 'Bayu Aji N':
                payment_each_date = 60000 + overtime_hours * 10000
            elif name == 'dani':
                payment_each_date = 70000 + overtime_hours * 10000
            else :
                payment_each_date = "Name Not Listed"

        else:
            if name == 'Alif':
                payment_each_date = 60000
            elif name == 'budi':
               payment_each_date = 70000
            elif name == 'adi':
                payment_each_date = 60000
            elif name == 'supriyanto':
               payment_each_date = 70000
            elif name == 'Edi':
                payment_each_date = 60000
            elif name == 'Tri Gunawan':
                payment_each_date = 60000
            elif name == 'Bayu Aji N':
                payment_each_date = 60000
            elif name == 'dani':
                payment_each_date = 70000
            else :
                payment_each_date = "Name Not Listed"

    else:
      if start_time > late_limit:
          if name == 'Alif':
              payment_each_date = 60000/2
          elif name == 'budi':
              payment_each_date = 70000/2
          elif name == 'adi':
              payment_each_date = 60000/2
          elif name == 'supriyanto':
              payment_each_date = 70000/2
          elif name == 'Edi':
              payment_each_date = 60000/2
          elif name == 'Tri Gunawan':
              payment_each_date = 60000/2
          elif name == 'Bayu Aji N':
              payment_each_date = 60000/2
          elif name == 'dani':
              payment_each_date = 70000/2
          else :
              payment_each_date = "Name Not Listed"
      else:
          if name == 'Alif':
              payment_each_date = 60000
          elif name == 'budi':
              payment_each_date = 70000
          elif name == 'adi':
              payment_each_date = 60000
          elif name == 'supriyanto':
              payment_each_date = 70000
          elif name == 'Edi':
              payment_each_date = 60000
          elif name == 'Tri Gunawan':
               payment_each_date = 60000
          elif name == 'Bayu Aji N':
               payment_each_date = 60000
          elif name == 'dani':
              payment_each_date = 70000
          else :
              payment_each_date = "Name Not Listed"

    # Add the total work hours, overtime hours, and payment as new columns to the dataframe
    df.loc[(df['Nama'] == name) & (df['Date'] == date), 'Hours Worked'] = hours_worked
    df.loc[(df['Nama'] == name) & (df['Date'] == date), 'Overtime Hours'] = overtime_hours
    df.loc[(df['Nama'] == name) & (df['Date'] == date), 'Payment Each Date'] = payment_each_date

holiday_status = df['Tgl/Waktu'].dt.normalize().isin(pd.DatetimeIndex(holidays_date))
# make new column for holiday with boolean value then merge with the original dataframe and place it in between date and time using merge
df = pd.merge(df, holiday_status.to_frame('Holiday'), left_index=True, right_index=True)
# make the payment each date column to 1.5 times and add 5000 if the holiday column is true
df.loc[df['Holiday'] == True, 'Payment Each Date'] = df['Payment Each Date'] * 1.5 + 5000

# Calculate the total payment from payment each date and insert it into new column named Total Payment
df_total = df.groupby(['Nama', 'Date'])['Payment Each Date'].max().groupby('Nama').sum().rename('Total Payment')
df = df.merge(df_total, how='left', on='Nama')

# Print the resulting dataframe
print(df)

# write DataFrame to excel
df.to_excel(excel_writer=r'/content/drive/MyDrive/Colab Notebooks/test.xlsx')
</code>
with this data when I run the program it can be processed and got correct result
but when I use this data I get error unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'
like below

so how do I fix it? is it the error on the data? or the program?
Comment: So what is the difference in the data? Some formatting? Extra spaces? A person's name missing? What error trapping do you do?
Comment: thats what im confused about, what are the difference because the error only happened in the 'Tgl/Waktu' Column
Comment: I am not going to go through your data for you... Try checking for extra spaces, or numbers out of range etc etc.
Comment: The data that works probably doesn't execute the line with the error.  As the error says, you can't subtract two `datetime.time` objects, so maybe the "good" data doesn't have any `end_time > overtime_threshold`.
Answer: The Answer to make the program can run is to convert the end_time and overtime_treshold into timedelta format, such as
<code>overtime_hours += (timedelta(hours=end_time.hour, minutes=end_time.minute, seconds=end_time.second) - timedelta(hours=overtime_threshold.hour, minutes=overtime_threshold.minute)).total_seconds() / 3600
</code>


Summation in differentiability proof

Question: I'm reading through the following proof on derivatives, but I'm having trouble understanding one specific part.
The proof states: Let $ n \in \mathbb{N} \cup \{0\} $ and $ f: \mathbb{R} \to \mathbb{R} $ be defined by $ f(x) = x^{n+1}$. Then, for $ x \neq a $
$$\frac{f(x)- f(a)}{x-a} = \frac{x^{n+1}-a^{n+1}}{x-a} = \sum_{k=0}^n x^{n-k}a^k $$
Could someone explain how you would get that summation? How are they equal to each other?
Comment: This is a common factorisation trick: multiply $x-a$ to the term on the RHS. Then you should get a difference of two summations, and you should notice that a lot of things cancel out (try it for small $n$ like $n=1,2$ to get an intuition). What you'll end up with is $x^{n+1} - a^{n+1}$
Comment: I'm sorry, I still don't understand. Also, the index of the summation is k but I should be using n = 1, 2?
Comment: @super do you know the summation expression for $x^n - a^n$ ? This is it.
Comment: See https://en.wikipedia.org/wiki/Polynomial_long_division
Answer: $$
\begin{align}
\sum_{k=0}^n x^{n-k} a^k
&= x^n \displaystyle \sum_{k=0}^n \left(\frac{a}{x}\right)^k \\
&= x^n \frac{1 - \left(\frac{a}{x}\right)^{n+1}}{1 - \frac{a}{x}} \\
&= \frac{x^{n+1} - a^{n+1}}{x-a}
\end{align}
$$
Comment: How do you obtain step 3 when you don't know the identity already?
Comment: How else would you simplify?
Answer: Note that
\begin{align}
(x-a)\cdot \left(\sum_{k=0}^n x^{n-k}a^k \right) &= (x-a)(x^n + x^{n-1}a + \dots + xa^{n-1} + a^n ) \\
&= (x^{n+1} + x^na + \dots + x^2 a^{n-1} + xa^n) \\
& -(x^na + x^{n-1}a^2 + \dots + xa^n + a^{n+1} )\\\\
&= x^{n+1} - a^{n+1}
\end{align}
To get the last equal sign, notice that a lot of terms cancel each other out. So, all there is to this is to expand everything out, and see that a huge chunk of terms cancel out. Now, dividing both sides by $x-a$ gives you the last equality.

Summation in differentiability proof


Differential operator in cylindrical and spherical coordinates

Question: I am trying to understand how to write the differential operator $\vec{r}\cdot\nabla$ in cylindrical and spherical coordinates.
Say, we have this equation (an illustrative example):
$$(\vec{r}\cdot\nabla) f=a$$
In Cartesian coordinates, this equation is
$$x\frac{\partial f}{\partial x}+y\frac{\partial f}{\partial y}+z\frac{\partial f}{\partial z}=a$$
How does one write this same equation in cylindrical and spherical coordinates?
Answer: Sphericals
By the chain rule,
$$ \frac{\partial f}{\partial r} = \frac{\partial x}{\partial r} \frac{\partial f}{\partial x} + \frac{\partial y}{\partial r} \frac{\partial f}{\partial y} + \frac{\partial z}{\partial r} \frac{\partial f}{\partial z}, $$
and $\partial x/\partial r = \cos{\theta}\cos{\phi} = x/r$, and similarly $\partial y/\partial r = y/r$, $\partial z/\partial r = z/r$, so
$$ \frac{\partial f}{\partial r} = \frac{x}{r} \frac{\partial f}{\partial x} + \frac{y}{r} \frac{\partial f}{\partial y} + \frac{z}{r} \frac{\partial f}{\partial z}. $$
Hence
$$ (\vec{r} \cdot \nabla) f = r\frac{\partial f}{\partial r}. $$
Cylindricals
In cylindricals $(\rho,\phi,z)$, the $z$ part does not change, while a similar argument shows that $\frac{\partial f}{\partial \rho} = \frac{x}{\rho} \frac{\partial f}{\partial x} + \frac{y}{\rho} \frac{\partial f}{\partial y}$, and so
$$ (\vec{r} \cdot \nabla)f = \rho\frac{\partial f}{\partial \rho} + z\frac{\partial f}{\partial z}. $$
Comment: Thank you for your answer!


Ggplot de um Data.frame em gráficos separados

Question: Tenho esse data.frame:
> df
           ind    m         X1       X2
1   2015-12-21   21     0.1431529 0.1426365
2   2015-12-21   42     0.1403679 0.1443714
3   2015-12-21   63     0.1467133 0.1466899
4   2015-12-21   84     0.1513388 0.1485589
5   2015-12-21  105     0.1543437 0.1504224
6   2015-12-21  126     0.1563804 0.1521211
7   2015-12-21  147     0.1578400 0.1540595
8   2015-12-21  168     0.1589353 0.1557416
9   2015-12-21  189     0.1597872 0.1570508
10  2015-12-21  210     0.1604689 0.1581820
11  2015-12-21  231     0.1610265 0.1591167
12  2015-12-21  252     0.1614913 0.1598340
13  2015-12-21  273     0.1618845 0.1609237
14  2015-12-21  294     0.1622215 0.1620525
15  2015-12-21  315     0.1625137 0.1630830
16  2015-12-21  336     0.1627693 0.1638686
17  2015-12-21  357     0.1629948 0.1645696
18  2015-12-21  378     0.1631953 0.1651773
19  2015-12-21  399     0.1633746 0.1656657
20  2015-12-21  420     0.1635361 0.1660847
21  2015-12-21  441     0.1636821 0.1664921
22  2015-12-21  462     0.1638149 0.1667551
23  2015-12-21  483     0.1639361 0.1669551
24  2015-12-21  504     0.1640473 0.1671720
25  2015-12-21  525     0.1641495 0.1673453
26  2015-12-21  546     0.1642439 0.1675000
27  2015-12-21  567     0.1643313 0.1676821
28  2015-12-21  588     0.1644124 0.1679642
29  2015-12-21  609     0.1644880 0.1681595
30  2015-12-21  630     0.1645585 0.1683756
31  2015-12-21  651     0.1646244 0.1684000
32  2015-12-21  672     0.1646863 0.1684000
33  2015-12-21  693     0.1647444 0.1683297
34  2015-12-21  714     0.1647990 0.1683000
35  2015-12-21  735     0.1648506 0.1683000
36  2015-12-21  756     0.1648993 0.1683000
37  2015-12-21  777     0.1649453 0.1682282
38  2015-12-21  798     0.1649890 0.1681198
39  2015-12-21  819     0.1650304 0.1680000
40  2015-12-21  840     0.1650697 0.1680000
41  2015-12-21  861     0.1651071 0.1678616
42  2015-12-21  882     0.1651427 0.1677899
43  2015-12-21  903     0.1651767 0.1676472
44  2015-12-21  924     0.1652091 0.1675540
45  2015-12-21  945     0.1652401 0.1674180
46  2015-12-21  966     0.1652697 0.1673603
47  2015-12-21  987     0.1652981 0.1672298
48  2015-12-21 1008     0.1653253 0.1671140
49  2015-12-21 1029     0.1653514 0.1669603
50  2015-12-21 1050     0.1653764 0.1668124
51  2015-12-21 1071     0.1654005 0.1667165
52  2015-12-21 1092     0.1654236 0.1665495
53  2015-12-21 1113     0.1654459 0.1664299
54  2015-12-21 1134     0.1654673 0.1663000
55  2015-12-21 1155     0.1654879 0.1662152
56  2015-12-21 1176     0.1655079 0.1661180
57  2015-12-21 1197     0.1655271 0.1660165
58  2015-12-21 1218     0.1655456 0.1659519
59  2015-12-21 1239     0.1655636 0.1657849
60  2015-12-21 1260     0.1655809 0.1657073
61  2015-12-21 1281     0.1655976 0.1655520
62  2015-12-21 1302     0.1656139 0.1654799
63  2015-12-21 1323     0.1656296 0.1653000
64  2015-12-21 1344     0.1656448 0.1652425
65  2015-12-21 1365     0.1656595 0.1651239
66  2015-12-21 1386     0.1656738 0.1650000
67  2015-12-21 1407     0.1656877 0.1648901
68  2015-12-21 1428     0.1657012 0.1648000
69  2015-12-21 1449     0.1657142 0.1647000
70  2015-12-21 1470     0.1657269 0.1646000
71  2015-12-21 1491     0.1657393 0.1644705
72  2015-12-21 1512     0.1657513 0.1644032
73  2015-12-21 1533     0.1657630 0.1644480
74  2015-12-21 1554     0.1657743 0.1645000
75  2015-12-21 1575     0.1657854 0.1645000
76  2015-12-21 1596     0.1657961 0.1646000
77  2015-12-21 1617     0.1658066 0.1646399
78  2015-12-21 1638     0.1658168 0.1647000
79  2015-12-21 1659     0.1658268 0.1647000
80  2015-12-21 1680     0.1658365 0.1647549
81  2015-12-21 1701     0.1658460 0.1648000
82  2015-12-21 1722     0.1658552 0.1648000
83  2015-12-21 1743     0.1658642 0.1648368
84  2015-12-21 1764     0.1658730 0.1649000
85  2015-12-21 1785     0.1658816 0.1649000
86  2015-12-21 1806     0.1658900 0.1648442
87  2015-12-21 1827     0.1658982 0.1648000
88  2015-12-21 1848     0.1659062 0.1648000
89  2015-12-21 1869     0.1659140 0.1647316
90  2015-12-21 1890     0.1659217 0.1647000
91  2015-12-21 1911     0.1659292 0.1647000
92  2015-12-21 1932     0.1659365 0.1646602
93  2015-12-21 1953     0.1659437 0.1646000
94  2015-12-21 1974     0.1659507 0.1646000
95  2015-12-21 1995     0.1659576 0.1646000
96  2015-12-21 2016     0.1659643 0.1645899
97  2015-12-21 2037     0.1659709 0.1645198
98  2015-12-21 2058     0.1659773 0.1645000
99  2015-12-21 2079     0.1659837 0.1645000
100 2015-12-21 2100     0.1659899 0.1645000
101 2015-12-21 2121     0.1659959 0.1644496
102 2015-12-21 2142     0.1660019 0.1644000
103 2015-12-21 2163     0.1660077 0.1644000
104 2015-12-21 2184     0.1660134 0.1643750
105 2015-12-21 2205     0.1660191 0.1643380
106 2015-12-21 2226     0.1660246 0.1643017
107 2015-12-21 2247     0.1660300 0.1643000
108 2015-12-21 2268     0.1660353 0.1642968
109 2015-12-21 2289     0.1660405 0.1642309
110 2015-12-21 2310     0.1660456 0.1641806
111 2015-12-21 2331     0.1660506 0.1641442
112 2015-12-21 2352     0.1660556 0.1641084
113 2015-12-21 2373     0.1660604 0.1641000
114 2015-12-21 2394     0.1660652 0.1640847
115 2015-12-21 2415     0.1660699 0.1640210
116 2015-12-21 2436     0.1660745 0.1639732
117 2015-12-21 2457     0.1660790 0.1639335
118 2015-12-21 2478     0.1660834 0.1639000
119 2015-12-21 2499     0.1660878 0.1638653
120 2015-12-21 2520     0.1660921 0.1638000

Observe que na primeira coluna só tenho uma data.
Para essa data quero plotar um gráfico onde o eixo x é a coluna "m" e o eixo x contem as colunas X1 e X2.
Para isso uso esse código:
ggplot(data=df, aes(x=df$m, y=df$X2, colour=ind))+
  xlab('m') + ylab('Taxas')+
  theme(legend.title=element_blank(), legend.position='top') +
  ggtitle('.')+
  geom_point()+ geom_line()+
  geom_point(aes(x=df$m,y = df$X1,colour=ind)) +
  geom_point(y = df$X1, color="black")+
  geom_line(y = df$X1, color="blue")+
  theme(axis.text = element_text(size = 12,colour="black"),axis.text.x=element_text(angle = 45))

O meu problema surge quando tenho mais de uma data. Por exemplo, quando tenho duas datas quero plotar 2 gráficos separados.
Queria só uma dica:
Segue o df com duas datas:
          ind    m        X1        X2
1   2015-12-21   21 0.1431529 0.1426365
2   2015-12-21   42 0.1403679 0.1443714
3   2015-12-21   63 0.1467133 0.1466899
4   2015-12-21   84 0.1513388 0.1485589
5   2015-12-21  105 0.1543437 0.1504224
6   2015-12-21  126 0.1563804 0.1521211
7   2015-12-21  147 0.1578400 0.1540595
8   2015-12-21  168 0.1589353 0.1557416
9   2015-12-21  189 0.1597872 0.1570508
10  2015-12-21  210 0.1604689 0.1581820
11  2015-12-21  231 0.1610265 0.1591167
12  2015-12-21  252 0.1614913 0.1598340
13  2015-12-21  273 0.1618845 0.1609237
14  2015-12-21  294 0.1622215 0.1620525
15  2015-12-21  315 0.1625137 0.1630830
16  2015-12-21  336 0.1627693 0.1638686
17  2015-12-21  357 0.1629948 0.1645696
18  2015-12-21  378 0.1631953 0.1651773
19  2015-12-21  399 0.1633746 0.1656657
20  2015-12-21  420 0.1635361 0.1660847
21  2015-12-21  441 0.1636821 0.1664921
22  2015-12-21  462 0.1638149 0.1667551
23  2015-12-21  483 0.1639361 0.1669551
24  2015-12-21  504 0.1640473 0.1671720
25  2015-12-21  525 0.1641495 0.1673453
26  2015-12-21  546 0.1642439 0.1675000
27  2015-12-21  567 0.1643313 0.1676821
28  2015-12-21  588 0.1644124 0.1679642
29  2015-12-21  609 0.1644880 0.1681595
30  2015-12-21  630 0.1645585 0.1683756
31  2015-12-21  651 0.1646244 0.1684000
32  2015-12-21  672 0.1646863 0.1684000
33  2015-12-21  693 0.1647444 0.1683297
34  2015-12-21  714 0.1647990 0.1683000
35  2015-12-21  735 0.1648506 0.1683000
36  2015-12-21  756 0.1648993 0.1683000
37  2015-12-21  777 0.1649453 0.1682282
38  2015-12-21  798 0.1649890 0.1681198
39  2015-12-21  819 0.1650304 0.1680000
40  2015-12-21  840 0.1650697 0.1680000
41  2015-12-21  861 0.1651071 0.1678616
42  2015-12-21  882 0.1651427 0.1677899
43  2015-12-21  903 0.1651767 0.1676472
44  2015-12-21  924 0.1652091 0.1675540
45  2015-12-21  945 0.1652401 0.1674180
46  2015-12-21  966 0.1652697 0.1673603
47  2015-12-21  987 0.1652981 0.1672298
48  2015-12-21 1008 0.1653253 0.1671140
49  2015-12-21 1029 0.1653514 0.1669603
50  2015-12-21 1050 0.1653764 0.1668124
51  2015-12-21 1071 0.1654005 0.1667165
52  2015-12-21 1092 0.1654236 0.1665495
53  2015-12-21 1113 0.1654459 0.1664299
54  2015-12-21 1134 0.1654673 0.1663000
55  2015-12-21 1155 0.1654879 0.1662152
56  2015-12-21 1176 0.1655079 0.1661180
57  2015-12-21 1197 0.1655271 0.1660165
58  2015-12-21 1218 0.1655456 0.1659519
59  2015-12-21 1239 0.1655636 0.1657849
60  2015-12-21 1260 0.1655809 0.1657073
61  2015-12-21 1281 0.1655976 0.1655520
62  2015-12-21 1302 0.1656139 0.1654799
63  2015-12-21 1323 0.1656296 0.1653000
64  2015-12-21 1344 0.1656448 0.1652425
65  2015-12-21 1365 0.1656595 0.1651239
66  2015-12-21 1386 0.1656738 0.1650000
67  2015-12-21 1407 0.1656877 0.1648901
68  2015-12-21 1428 0.1657012 0.1648000
69  2015-12-21 1449 0.1657142 0.1647000
70  2015-12-21 1470 0.1657269 0.1646000
71  2015-12-21 1491 0.1657393 0.1644705
72  2015-12-21 1512 0.1657513 0.1644032
73  2015-12-21 1533 0.1657630 0.1644480
74  2015-12-21 1554 0.1657743 0.1645000
75  2015-12-21 1575 0.1657854 0.1645000
76  2015-12-21 1596 0.1657961 0.1646000
77  2015-12-21 1617 0.1658066 0.1646399
78  2015-12-21 1638 0.1658168 0.1647000
79  2015-12-21 1659 0.1658268 0.1647000
80  2015-12-21 1680 0.1658365 0.1647549
81  2015-12-21 1701 0.1658460 0.1648000
82  2015-12-21 1722 0.1658552 0.1648000
83  2015-12-21 1743 0.1658642 0.1648368
84  2015-12-21 1764 0.1658730 0.1649000
85  2015-12-21 1785 0.1658816 0.1649000
86  2015-12-21 1806 0.1658900 0.1648442
87  2015-12-21 1827 0.1658982 0.1648000
88  2015-12-21 1848 0.1659062 0.1648000
89  2015-12-21 1869 0.1659140 0.1647316
90  2015-12-21 1890 0.1659217 0.1647000
91  2015-12-21 1911 0.1659292 0.1647000
92  2015-12-21 1932 0.1659365 0.1646602
93  2015-12-21 1953 0.1659437 0.1646000
94  2015-12-21 1974 0.1659507 0.1646000
95  2015-12-21 1995 0.1659576 0.1646000
96  2015-12-21 2016 0.1659643 0.1645899
97  2015-12-21 2037 0.1659709 0.1645198
98  2015-12-21 2058 0.1659773 0.1645000
99  2015-12-21 2079 0.1659837 0.1645000
100 2015-12-21 2100 0.1659899 0.1645000
101 2015-12-21 2121 0.1659959 0.1644496
102 2015-12-21 2142 0.1660019 0.1644000
103 2015-12-21 2163 0.1660077 0.1644000
104 2015-12-21 2184 0.1660134 0.1643750
105 2015-12-21 2205 0.1660191 0.1643380
106 2015-12-21 2226 0.1660246 0.1643017
107 2015-12-21 2247 0.1660300 0.1643000
108 2015-12-21 2268 0.1660353 0.1642968
109 2015-12-21 2289 0.1660405 0.1642309
110 2015-12-21 2310 0.1660456 0.1641806
111 2015-12-21 2331 0.1660506 0.1641442
112 2015-12-21 2352 0.1660556 0.1641084
113 2015-12-21 2373 0.1660604 0.1641000
114 2015-12-21 2394 0.1660652 0.1640847
115 2015-12-21 2415 0.1660699 0.1640210
116 2015-12-21 2436 0.1660745 0.1639732
117 2015-12-21 2457 0.1660790 0.1639335
118 2015-12-21 2478 0.1660834 0.1639000
119 2015-12-21 2499 0.1660878 0.1638653
120 2015-12-21 2520 0.1660921 0.1638000
121 2015-12-22   21 0.1431529 0.1426524
122 2015-12-22   42 0.1403679 0.1444571
123 2015-12-22   63 0.1467133 0.1466772
124 2015-12-22   84 0.1513388 0.1482843
125 2015-12-22  105 0.1543437 0.1504085
126 2015-12-22  126 0.1563804 0.1518340
127 2015-12-22  147 0.1578400 0.1536498
128 2015-12-22  168 0.1589353 0.1551931
129 2015-12-22  189 0.1597872 0.1562000
130 2015-12-22  210 0.1604689 0.1571264
131 2015-12-22  231 0.1610265 0.1580308
132 2015-12-22  252 0.1614913 0.1587339
133 2015-12-22  273 0.1618845 0.1598251
134 2015-12-22  294 0.1622215 0.1610027
135 2015-12-22  315 0.1625137 0.1619547
136 2015-12-22  336 0.1627693 0.1628018
137 2015-12-22  357 0.1629948 0.1636025
138 2015-12-22  378 0.1631953 0.1642695
139 2015-12-22  399 0.1633746 0.1647928
140 2015-12-22  420 0.1635361 0.1652014
141 2015-12-22  441 0.1636821 0.1656103
142 2015-12-22  462 0.1638149 0.1659284
143 2015-12-22  483 0.1639361 0.1662283
144 2015-12-22  504 0.1640473 0.1664581
145 2015-12-22  525 0.1641495 0.1666965
146 2015-12-22  546 0.1642439 0.1668902
147 2015-12-22  567 0.1643313 0.1670911
148 2015-12-22  588 0.1644124 0.1673821
149 2015-12-22  609 0.1644880 0.1676236
150 2015-12-22  630 0.1645585 0.1677935
151 2015-12-22  651 0.1646244 0.1678000
152 2015-12-22  672 0.1646863 0.1678000
153 2015-12-22  693 0.1647444 0.1678000
154 2015-12-22  714 0.1647990 0.1678000
155 2015-12-22  735 0.1648506 0.1678000
156 2015-12-22  756 0.1648993 0.1678000
157 2015-12-22  777 0.1649453 0.1677211
158 2015-12-22  798 0.1649890 0.1677000
159 2015-12-22  819 0.1650304 0.1676000
160 2015-12-22  840 0.1650697 0.1676000
161 2015-12-22  861 0.1651071 0.1675585
162 2015-12-22  882 0.1651427 0.1675000
163 2015-12-22  903 0.1651767 0.1673857
164 2015-12-22  924 0.1652091 0.1672494
165 2015-12-22  945 0.1652401 0.1672000
166 2015-12-22  966 0.1652697 0.1670559
167 2015-12-22  987 0.1652981 0.1670000
168 2015-12-22 1008 0.1653253 0.1669093
169 2015-12-22 1029 0.1653514 0.1668119
170 2015-12-22 1050 0.1653764 0.1667000
171 2015-12-22 1071 0.1654005 0.1666000
172 2015-12-22 1092 0.1654236 0.1664445
173 2015-12-22 1113 0.1654459 0.1663618
174 2015-12-22 1134 0.1654673 0.1662899
175 2015-12-22 1155 0.1654879 0.1661076
176 2015-12-22 1176 0.1655079 0.1660090
177 2015-12-22 1197 0.1655271 0.1660000
178 2015-12-22 1218 0.1655456 0.1658472
179 2015-12-22 1239 0.1655636 0.1657843
180 2015-12-22 1260 0.1655809 0.1657038
181 2015-12-22 1281 0.1655976 0.1656472
182 2015-12-22 1302 0.1656139 0.1656000
183 2015-12-22 1323 0.1656296 0.1655888
184 2015-12-22 1344 0.1656448 0.1655000
185 2015-12-22 1365 0.1656595 0.1654588
186 2015-12-22 1386 0.1656738 0.1654000
187 2015-12-22 1407 0.1656877 0.1654000
188 2015-12-22 1428 0.1657012 0.1653000
189 2015-12-22 1449 0.1657142 0.1653000
190 2015-12-22 1470 0.1657269 0.1652397
191 2015-12-22 1491 0.1657393 0.1652000
192 2015-12-22 1512 0.1657513 0.1652000
193 2015-12-22 1533 0.1657630 0.1651473
194 2015-12-22 1554 0.1657743 0.1651000
195 2015-12-22 1575 0.1657854 0.1651000
196 2015-12-22 1596 0.1657961 0.1650366
197 2015-12-22 1617 0.1658066 0.1650000
198 2015-12-22 1638 0.1658168 0.1650000
199 2015-12-22 1659 0.1658268 0.1649378
200 2015-12-22 1680 0.1658365 0.1649000
201 2015-12-22 1701 0.1658460 0.1649000
202 2015-12-22 1722 0.1658552 0.1648397
203 2015-12-22 1743 0.1658642 0.1648000
204 2015-12-22 1764 0.1658730 0.1648000
205 2015-12-22 1785 0.1658816 0.1647451
206 2015-12-22 1806 0.1658900 0.1647000
207 2015-12-22 1827 0.1658982 0.1646888
208 2015-12-22 1848 0.1659062 0.1646000
209 2015-12-22 1869 0.1659140 0.1646000
210 2015-12-22 1890 0.1659217 0.1645000
211 2015-12-22 1911 0.1659292 0.1645000
212 2015-12-22 1932 0.1659365 0.1644572
213 2015-12-22 1953 0.1659437 0.1644000
214 2015-12-22 1974 0.1659507 0.1644000
215 2015-12-22 1995 0.1659576 0.1643545
216 2015-12-22 2016 0.1659643 0.1643000
217 2015-12-22 2037 0.1659709 0.1643000
218 2015-12-22 2058 0.1659773 0.1643395
219 2015-12-22 2079 0.1659837 0.1643904
220 2015-12-22 2100 0.1659899 0.1644000
221 2015-12-22 2121 0.1659959 0.1644000
222 2015-12-22 2142 0.1660019 0.1644000
223 2015-12-22 2163 0.1660077 0.1644000
224 2015-12-22 2184 0.1660134 0.1644268
225 2015-12-22 2205 0.1660191 0.1644638
226 2015-12-22 2226 0.1660246 0.1645000
227 2015-12-22 2247 0.1660300 0.1645000
228 2015-12-22 2268 0.1660353 0.1644937
229 2015-12-22 2289 0.1660405 0.1644278
230 2015-12-22 2310 0.1660456 0.1643789
231 2015-12-22 2331 0.1660506 0.1643425
232 2015-12-22 2352 0.1660556 0.1643067
233 2015-12-22 2373 0.1660604 0.1643000
234 2015-12-22 2394 0.1660652 0.1642816
235 2015-12-22 2415 0.1660699 0.1642180
236 2015-12-22 2436 0.1660745 0.1641718
237 2015-12-22 2457 0.1660790 0.1641328
238 2015-12-22 2478 0.1660834 0.1641000
239 2015-12-22 2499 0.1660878 0.1640622
240 2015-12-22 2520 0.1660921 0.1640000

Answer: Neste caso você pode incluir mais um elemento ao seu gráfico especificando que a variável ind vai gerar diferentes facetas, isto é, facet_wrap(~ind):
ggplot(data=df, aes(x=df$m, y=df$X2, colour=ind))+
  xlab('m') + ylab('Taxas')+
  theme(legend.title=element_blank(), legend.position='top') +
  ggtitle('.')+
  geom_point()+ geom_line()+
  geom_point(aes(x=df$m,y = df$X1,colour=ind)) +
  geom_point(y = df$X1, color="black")+
  geom_line(y = df$X1, color="blue")+
  theme(axis.text = element_text(size = 12,colour="black"),axis.text.x=element_text(angle = 45)) +
  facet_wrap(~ind)


What is the intuition of momentum term in the neural network back propagation?

Question: I am going through the derivation of neural network using this lecture pdf
And I am stuck on equation $(21)$
Note on notation:

Activation function of layer $j$ is $y_j$
Summation of weights of layer $j$ is $x_j$
final label is $t$

I am trying to figure out where
$$\eta \Delta w_{kj} (n-1)$$
is coming from in the final equation $(21)$
$$  \Delta w_{kj}(n) = \alpha \delta_j y_k + \eta \Delta w_{kj} (n-1)$$
The author mentioned that it is a momentum term without really elaborating on it.
I thought $\Delta w_{kj}$ calculation is the following
$$\Delta w_{kj} = - \alpha \frac{\partial E}{\partial w_{kj}}$$
for 1 layer before final output layer:
$$\Delta w_{kj} = - \alpha (-(t_j-y_j))y_j(1-y_j)y_k$$
for all other layers:
$$\Delta w_{kj} = - \alpha (\delta_{i}w_{ji}) y_j(1-y_j)y_k$$
So what is the momentum term?
Can someone help me out ?
Comment: Check this article: http://neupy.com/2015/07/04/visualize_backpropagation_algorithms.html#momentum. It should give you some intuition about momentum algorithm.
Answer: Since you are asking for intuition, here's the general idea:
Imagine that you are using stochastic gradient descent (SGD) to traverse the surface of the loss function. Further imagine that that surface looks like a mountain and that you are starting near the top. The surface has many small crags and lips but is clearly headed down to a valley. As you traverse the surface using SGD, the magnitude - and sign - of the derivative changes often, and so there is a great deal of fluctuation in the direction and speed that you take down the mountain. If you include a momentum term, then instead of just relying on the gradient at each new stopping point to determine your movement, your direction now also depends on the size and direction of your movement in the previous update. And since the amount and direction you moved last update also depended on the update before it you can see that each movement depends on the entire history of previous movements. So pretty soon you're running down the mountain toward the valley.
Notice that the further you are in time from an update, the less important it is for determining your current update, since, if you expand the momentum term at time $t$ then the contribution of the update from time $t-k$ is:
\begin{equation}
\alpha^{k+1}\Delta\omega_{t-k}
\end{equation}
Where $\alpha\in[0,1]$ is the momentum and $\Delta\omega_{t-k}$ is the weight update at time $t-k$
Answer: Firstly, let's pretend we have just started training so that:
\begin{equation}
n = 0
\end{equation}
and
\begin{equation}
\omega_{kj}(0) = \alpha\delta_jy_k
\end{equation}
because this is the first time step. If we go one training step further to
\begin{equation}
n = 1
\end{equation}
then:
\begin{equation}
\omega_{kj}(1) = \alpha\delta_jy_k + \eta\omega_{kj}(0)
\end{equation}
and one more to
\begin{equation}
n = 2
\end{equation}
\begin{equation}
\omega_{kj}(2) = \alpha\delta_jy_k + \eta\omega_{kj}(1)
\end{equation}
and substitute:
\begin{equation}
\omega_{kj}(2) = \alpha\delta_{j2}y_{k2} + \eta(\alpha\delta_{j1}y_{k1} + \eta\omega_{kj}(0))
\end{equation}
You can see that if we continued this trend, even a time step of
\begin{equation}
n = 200
\end{equation}
would still slightly be influenced by the very first weight gradient at time step 0 (but very very slightly). This is the concept of momentum: velocity with a memory of past velocities. This concept is directly related to physics.
If I push a block 10m/s forward (think of that as my first time step) and then I push it at -20m/s (my second time step); then via momentum this would be:
new speed = -20m/s + u(100m/s) where u is friction (or in our case eta). So if friction is 0.1, my final speed will actually be -20 + (0.1)(100) = -10. I am closer to -20 but I am not completely there. If I push the block again at -20m/s my result is: -10 + (0.1)(-20) = -12, and I am closer to the speed I wish to attain.
In the concept of neural networks, this means if I am going down the gradient and searching for the minimum, I do not want to drastically change directions at each time step because some directions could lead to valleys or local minima. Therefore I want to go the direction in which most of my weight gradients push me. Changing this direction usually requires a large number of weight gradients against my current gradient 'flow'.