问:
Drawing on top of controls inside a panel (C# WinForms)
I know this question had been asked more than a few times, but so far I haven't been able to find a good solution for it.

I've got a panel with other control on it.

I want to draw a line on it and on top of all the controls in the panel

I came across 3 types of solutions (non of them worked the way I wanted) :

Get the desktop DC and Draw on the screen.

This will draw on other applications if they overlap the form.

Overriding the panel's "CreateParams":

=

```<code>protected override CreateParams CreateParams {
  get {
    CreateParams cp;
    cp = base.CreateParams;
    cp.Style &= ~0x04000000; //WS_CLIPSIBLINGS
    cp.Style &= ~0x02000000; //WS_CLIPCHILDREN
    return cp;
  }
}
</code>```

//NOTE I've also tried disabling WS_CLIPSIBLINGS

and then drawing the line OnPaint().
But... Since the panel's OnPaint is called before the OnPaint of the controls in it,
the drawing of the controls inside simply paints on top of the line.

I've seen someone suggest using a message filter to listen to WM_PAINT mesages, and use a timer, but I don't think this solution is either "good practice" or effective.

What would you do ?  Decide that the controls inside have finished drawing after X ms, and set the timer to X ms ?

This screen shot shows the panel with WS_CLIPSIBLINGS and WS_CLIPCHILDREN turned off.

The Blue line is painted at the Panel's OnPaint, and simply being painted on by the textboxes and label.

The Red line is painted on top only because it's not being painted from the panel's OnPaint (It's actually painted as a result of a Button being clicked)

3rd: Creating a transparent layer and drawing on top of that layer.

I've created a transparent control using:

```<code>protected override CreateParams CreateParams {
  get {
    CreateParams cp = base.CreateParams;
    cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
    return cp;
  }
}
</code>```

The problem is still, putting the transparent control on top of the Panel and all its controls.

I've tried bringing it to the front using: "BringToFront()" , but it didn't seem to help.

I've put it in the Line control's OnPaint() handler.

Should I try putting it somewhere else ??

- This also creates issue with having another control on top of the panel. (catching the mouse clicks etc..)

Any help would be greatly appreciated!

**EDIT:
The black line is a sample of what I was trying to do. (used windows paint to paint it)

答:
EDIT Found a way to get rid of the recursive painting issue I had. So, now, to me, this looks very, very, very close to what you want to achieve.

Here's what I could come up with. It uses approach #3 outlined in the original question. The code is somewhat lengthy because three classes are involved:

A private class called DecorationCanvas. This derives from Panel and uses WS_EX_TRANSPARENT to provide a transparent canvas to draw our stuff on

The panel class itself, I called it DecoratedPanel, it derives from Panel

A designer class called DecoratedPanelDesigner for the panel, to make sure that the ZOrder can be preserved during Design time.

The basic approach is:

In the constructor of the DecoratedPanel, create an instance of DecorationCanvas and add it to the DecoratedPanel Controls collection.

Override OnControlAdded and OnControlRemoved, to automatically hook/unhook paint events for child controls, and to make sure the DecorationCanvas stays on top of the ZOrder.

Whenever a contained control paints, invalidate the corresponding DecorationCanvas rectangle.

Override OnResize and OnSizeChanged to make sure the DecorationCanvas has the same size as the DecoratedPanel. (I tried to accomplish this using the Anchor property, but it failed somehow).

Provide an internal method to reset the DecorationCanvas ZOrder from within the DecoratedPanelDesigner.

Works fine on my system (VS2010 / .net4 / Windows XP SP3). Here's the code:

```<code>using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace WindowsFormsApplication3
{
  [Designer("WindowsFormsApplication3.DecoratedPanelDesigner")]
  public class DecoratedPanel : Panel
  {
    #region decorationcanvas

    // this is an internal transparent panel.
    // This is our canvas we'll draw the lines on ...
    private class DecorationCanvas : Panel
    {
      public DecorationCanvas()
      {
        // don't paint the background
        SetStyle(ControlStyles.Opaque, true);
      }

      protected override CreateParams CreateParams
      {
        get
        {
          // use transparency
          CreateParams cp = base.CreateParams;
          cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
          return cp;
        }
      }
    }

    #endregion

    private DecorationCanvas _decorationCanvas;

    public DecoratedPanel()
    {
      // add our DecorationCanvas to our panel control
      _decorationCanvas = new DecorationCanvas();
      _decorationCanvas.Name = "myInternalOverlayPanel";
      _decorationCanvas.Size = ClientSize;
      _decorationCanvas.Location = new Point(0, 0);
      // this prevents the DecorationCanvas to catch clicks and the like
      _decorationCanvas.Enabled = false;
      _decorationCanvas.Paint += new PaintEventHandler(decoration_Paint);
      Controls.Add(_decorationCanvas);
    }

    protected override void Dispose(bool disposing)
    {
      if (disposing && _decorationCanvas != null)
      {
        // be a good citizen and clean up after yourself

        _decorationCanvas.Paint -= new PaintEventHandler(decoration_Paint);
        Controls.Remove(_decorationCanvas);
        _decorationCanvas = null;
      }

      base.Dispose(disposing);
    }

    void decoration_Paint(object sender, PaintEventArgs e)
    {
      // --- PAINT HERE ---
      e.Graphics.DrawLine(Pens.Red, 0, 0, ClientSize.Width, ClientSize.Height);
    }

    protected override void OnControlAdded(ControlEventArgs e)
    {
      base.OnControlAdded(e);

      if (IsInDesignMode)
        return;

      // Hook paint event and make sure we stay on top
      if (!_decorationCanvas.Equals(e.Control))
        e.Control.Paint += new PaintEventHandler(containedControl_Paint);

      ResetDecorationZOrder();
    }

    protected override void OnControlRemoved(ControlEventArgs e)
    {
      base.OnControlRemoved(e);

      if (IsInDesignMode)
        return;

      // Unhook paint event
      if (!_decorationCanvas.Equals(e.Control))
        e.Control.Paint -= new PaintEventHandler(containedControl_Paint);
    }

    /// <summary>
    /// If contained controls are updated, invalidate the corresponding DecorationCanvas area
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void containedControl_Paint(object sender, PaintEventArgs e)
    {
      Control c = sender as Control;

      if (c == null)
        return;

      _decorationCanvas.Invalidate(new Rectangle(c.Left, c.Top, c.Width, c.Height));
    }

    protected override void OnResize(EventArgs eventargs)
    {
      base.OnResize(eventargs);
      // make sure we're covering the panel control
      _decorationCanvas.Size = ClientSize;
    }

    protected override void OnSizeChanged(EventArgs e)
    {
      base.OnSizeChanged(e);
      // make sure we're covering the panel control
      _decorationCanvas.Size = ClientSize;
    }

    /// <summary>
    /// This is marked internal because it gets called from the designer
    /// to make sure our DecorationCanvas stays on top of the ZOrder.
    /// </summary>
    internal void ResetDecorationZOrder()
    {
      if (Controls.GetChildIndex(_decorationCanvas) != 0)
        Controls.SetChildIndex(_decorationCanvas, 0);
    }

    private bool IsInDesignMode
    {
      get
      {
        return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime;
      }
    }
  }

  /// <summary>
  /// Unfortunately, the default designer of the standard panel is not a public class
  /// So we'll have to build a new designer out of another one. Since Panel inherits from
  /// ScrollableControl, let's try a ScrollableControlDesigner ...
  /// </summary>
  public class DecoratedPanelDesigner : ScrollableControlDesigner
  {
    private IComponentChangeService _changeService;

    public override void Initialize(IComponent component)
    {
      base.Initialize(component);

      // Acquire a reference to IComponentChangeService.
      this._changeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;

      // Hook the IComponentChangeService event
      if (this._changeService != null)
        this._changeService.ComponentChanged += new ComponentChangedEventHandler(_changeService_ComponentChanged);
    }

    /// <summary>
    /// Try and handle ZOrder changes at design time
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void _changeService_ComponentChanged(object sender, ComponentChangedEventArgs e)
    {
      Control changedControl = e.Component as Control;
      if (changedControl == null)
        return;

      DecoratedPanel panelPaint = Control as DecoratedPanel;

      if (panelPaint == null)
        return;

      // if the ZOrder of controls contained within our panel changes, the
      // changed control is our control
      if (Control.Equals(panelPaint))
        panelPaint.ResetDecorationZOrder();
    }

    protected override void Dispose(bool disposing)
    {
      if (disposing)
      {
        if (this._changeService != null)
        {
          // Unhook the event handler
          this._changeService.ComponentChanged -= new ComponentChangedEventHandler(_changeService_ComponentChanged);
          this._changeService = null;
        }
      }

      base.Dispose(disposing);
    }

    /// <summary>
    /// If the panel has BorderStyle.None, a dashed border needs to be drawn around it
    /// </summary>
    /// <param name="pe"></param>
    protected override void OnPaintAdornments(PaintEventArgs pe)
    {
      base.OnPaintAdornments(pe);

      Panel panel = Control as Panel;
      if (panel == null)
        return;

      if (panel.BorderStyle == BorderStyle.None)
      {
        using (Pen p = new Pen(SystemColors.ControlDark))
        {
          p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
          pe.Graphics.DrawRectangle(p, 0, 0, Control.Width - 1, Control.Height - 1);
        }
      }
    }
  }
}
</code>```

Let me know what you think ...

OwnerDisplayName: dtroy

Body:
I know this question had been asked more than a few times, but so far I haven't been able to find a good solution for it.

I've got a panel with other control on it.

I want to draw a line on it and on top of all the controls in the panel

I came across 3 types of solutions (non of them worked the way I wanted) :

Get the desktop DC and Draw on the screen.

This will draw on other applications if they overlap the form.

Overriding the panel's "CreateParams":

=

protected override CreateParams CreateParams {
  get {
    CreateParams cp;
    cp = base.CreateParams;
    cp.Style &= ~0x04000000; //WS_CLIPSIBLINGS
    cp.Style &= ~0x02000000; //WS_CLIPCHILDREN
    return cp;
  }
}

//NOTE I've also tried disabling WS_CLIPSIBLINGS

and then drawing the line OnPaint().
But... Since the panel's OnPaint is called before the OnPaint of the controls in it,
the drawing of the controls inside simply paints on top of the line.

I've seen someone suggest using a message filter to listen to WM_PAINT mesages, and use a timer, but I don't think this solution is either "good practice" or effective.

What would you do ?  Decide that the controls inside have finished drawing after X ms, and set the timer to X ms ?

This screen shot shows the panel with WS_CLIPSIBLINGS and WS_CLIPCHILDREN turned off.

The Blue line is painted at the Panel's OnPaint, and simply being painted on by the textboxes and label.

The Red line is painted on top only because it's not being painted from the panel's OnPaint (It's actually painted as a result of a Button being clicked)

3rd: Creating a transparent layer and drawing on top of that layer.

I've created a transparent control using:

protected override CreateParams CreateParams {
  get {
    CreateParams cp = base.CreateParams;
    cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
    return cp;
  }
}

The problem is still, putting the transparent control on top of the Panel and all its controls.

I've tried bringing it to the front using: "BringToFront()" , but it didn't seem to help.

I've put it in the Line control's OnPaint() handler.

Should I try putting it somewhere else ??

- This also creates issue with having another control on top of the panel. (catching the mouse clicks etc..)

Any help would be greatly appreciated!

**EDIT:
The black line is a sample of what I was trying to do. (used windows paint to paint it)

LastEditorDisplayName: Jason Jackson

Body:
EDIT Found a way to get rid of the recursive painting issue I had. So, now, to me, this looks very, very, very close to what you want to achieve.

Here's what I could come up with. It uses approach #3 outlined in the original question. The code is somewhat lengthy because three classes are involved:

A private class called DecorationCanvas. This derives from Panel and uses WS_EX_TRANSPARENT to provide a transparent canvas to draw our stuff on

The panel class itself, I called it DecoratedPanel, it derives from Panel

A designer class called DecoratedPanelDesigner for the panel, to make sure that the ZOrder can be preserved during Design time.

The basic approach is:

In the constructor of the DecoratedPanel, create an instance of DecorationCanvas and add it to the DecoratedPanel Controls collection.

Override OnControlAdded and OnControlRemoved, to automatically hook/unhook paint events for child controls, and to make sure the DecorationCanvas stays on top of the ZOrder.

Whenever a contained control paints, invalidate the corresponding DecorationCanvas rectangle.

Override OnResize and OnSizeChanged to make sure the DecorationCanvas has the same size as the DecoratedPanel. (I tried to accomplish this using the Anchor property, but it failed somehow).

Provide an internal method to reset the DecorationCanvas ZOrder from within the DecoratedPanelDesigner.

Works fine on my system (VS2010 / .net4 / Windows XP SP3). Here's the code:

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace WindowsFormsApplication3
{
  [Designer("WindowsFormsApplication3.DecoratedPanelDesigner")]
  public class DecoratedPanel : Panel
  {
    #region decorationcanvas

    // this is an internal transparent panel.
    // This is our canvas we'll draw the lines on ...
    private class DecorationCanvas : Panel
    {
      public DecorationCanvas()
      {
        // don't paint the background
        SetStyle(ControlStyles.Opaque, true);
      }

      protected override CreateParams CreateParams
      {
        get
        {
          // use transparency
          CreateParams cp = base.CreateParams;
          cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
          return cp;
        }
      }
    }

    #endregion

    private DecorationCanvas _decorationCanvas;

    public DecoratedPanel()
    {
      // add our DecorationCanvas to our panel control
      _decorationCanvas = new DecorationCanvas();
      _decorationCanvas.Name = "myInternalOverlayPanel";
      _decorationCanvas.Size = ClientSize;
      _decorationCanvas.Location = new Point(0, 0);
      // this prevents the DecorationCanvas to catch clicks and the like
      _decorationCanvas.Enabled = false;
      _decorationCanvas.Paint += new PaintEventHandler(decoration_Paint);
      Controls.Add(_decorationCanvas);
    }

    protected override void Dispose(bool disposing)
    {
      if (disposing && _decorationCanvas != null)
      {
        // be a good citizen and clean up after yourself

        _decorationCanvas.Paint -= new PaintEventHandler(decoration_Paint);
        Controls.Remove(_decorationCanvas);
        _decorationCanvas = null;
      }

      base.Dispose(disposing);
    }

    void decoration_Paint(object sender, PaintEventArgs e)
    {
      // --- PAINT HERE ---
      e.Graphics.DrawLine(Pens.Red, 0, 0, ClientSize.Width, ClientSize.Height);
    }

    protected override void OnControlAdded(ControlEventArgs e)
    {
      base.OnControlAdded(e);

      if (IsInDesignMode)
        return;

      // Hook paint event and make sure we stay on top
      if (!_decorationCanvas.Equals(e.Control))
        e.Control.Paint += new PaintEventHandler(containedControl_Paint);

      ResetDecorationZOrder();
    }

    protected override void OnControlRemoved(ControlEventArgs e)
    {
      base.OnControlRemoved(e);

      if (IsInDesignMode)
        return;

      // Unhook paint event
      if (!_decorationCanvas.Equals(e.Control))
        e.Control.Paint -= new PaintEventHandler(containedControl_Paint);
    }

    /// <summary>
    /// If contained controls are updated, invalidate the corresponding DecorationCanvas area
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void containedControl_Paint(object sender, PaintEventArgs e)
    {
      Control c = sender as Control;

      if (c == null)
        return;

      _decorationCanvas.Invalidate(new Rectangle(c.Left, c.Top, c.Width, c.Height));
    }

    protected override void OnResize(EventArgs eventargs)
    {
      base.OnResize(eventargs);
      // make sure we're covering the panel control
      _decorationCanvas.Size = ClientSize;
    }

    protected override void OnSizeChanged(EventArgs e)
    {
      base.OnSizeChanged(e);
      // make sure we're covering the panel control
      _decorationCanvas.Size = ClientSize;
    }

    /// <summary>
    /// This is marked internal because it gets called from the designer
    /// to make sure our DecorationCanvas stays on top of the ZOrder.
    /// </summary>
    internal void ResetDecorationZOrder()
    {
      if (Controls.GetChildIndex(_decorationCanvas) != 0)
        Controls.SetChildIndex(_decorationCanvas, 0);
    }

    private bool IsInDesignMode
    {
      get
      {
        return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime;
      }
    }
  }

  /// <summary>
  /// Unfortunately, the default designer of the standard panel is not a public class
  /// So we'll have to build a new designer out of another one. Since Panel inherits from
  /// ScrollableControl, let's try a ScrollableControlDesigner ...
  /// </summary>
  public class DecoratedPanelDesigner : ScrollableControlDesigner
  {
    private IComponentChangeService _changeService;

    public override void Initialize(IComponent component)
    {
      base.Initialize(component);

      // Acquire a reference to IComponentChangeService.
      this._changeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;

      // Hook the IComponentChangeService event
      if (this._changeService != null)
        this._changeService.ComponentChanged += new ComponentChangedEventHandler(_changeService_ComponentChanged);
    }

    /// <summary>
    /// Try and handle ZOrder changes at design time
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void _changeService_ComponentChanged(object sender, ComponentChangedEventArgs e)
    {
      Control changedControl = e.Component as Control;
      if (changedControl == null)
        return;

      DecoratedPanel panelPaint = Control as DecoratedPanel;

      if (panelPaint == null)
        return;

      // if the ZOrder of controls contained within our panel changes, the
      // changed control is our control
      if (Control.Equals(panelPaint))
        panelPaint.ResetDecorationZOrder();
    }

    protected override void Dispose(bool disposing)
    {
      if (disposing)
      {
        if (this._changeService != null)
        {
          // Unhook the event handler
          this._changeService.ComponentChanged -= new ComponentChangedEventHandler(_changeService_ComponentChanged);
          this._changeService = null;
        }
      }

      base.Dispose(disposing);
    }

    /// <summary>
    /// If the panel has BorderStyle.None, a dashed border needs to be drawn around it
    /// </summary>
    /// <param name="pe"></param>
    protected override void OnPaintAdornments(PaintEventArgs pe)
    {
      base.OnPaintAdornments(pe);

      Panel panel = Control as Panel;
      if (panel == null)
        return;

      if (panel.BorderStyle == BorderStyle.None)
      {
        using (Pen p = new Pen(SystemColors.ControlDark))
        {
          p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
          pe.Graphics.DrawRectangle(p, 0, 0, Control.Width - 1, Control.Height - 1);
        }
      }
    }
  }
}

Let me know what you think ...


来源: stackexchange

问:
How can I get the full object in Node.js's console.log(), rather than '[Object]'?
I have this object:

```<code>const myObject = {
   "a":"a",
   "b":{
      "c":"c",
      "d":{
         "e":"e",
         "f":{
            "g":"g",
            "h":{
               "i":"i"
            }
         }
      }
   }
};
</code>```

But when I try to show it using console.log(myObject), I receive this output:

```<code>{ a: 'a', b: { c: 'c', d: { e: 'e', f: [Object] } } }
</code>```

How can I get the full object, including the content of property f?

答:
JSON.stringify()

```<code>let myVar = {a: {b: {c: 1}}};
console.log(JSON.stringify( myVar, null, 4 ))
</code>```

Great for deep inspection of data objects. This approach works on nested arrays and nested objects with arrays.

ContentLicense: CC BY-SA 4.0

Body:
I have this object:

const myObject = {
   "a":"a",
   "b":{
      "c":"c",
      "d":{
         "e":"e",
         "f":{
            "g":"g",
            "h":{
               "i":"i"
            }
         }
      }
   }
};

But when I try to show it using console.log(myObject), I receive this output:

{ a: 'a', b: { c: 'c', d: { e: 'e', f: [Object] } } }

How can I get the full object, including the content of property f?

Body:
JSON.stringify()

let myVar = {a: {b: {c: 1}}};
console.log(JSON.stringify( myVar, null, 4 ))

Great for deep inspection of data objects. This approach works on nested arrays and nested objects with arrays.


问:
How to make two legends using ggplot 2?
I am rather new to plotting graphs in R. I'm trying to create two legends similar to the picture below. The picture below is of data from the previous year and I'm updating it but need to rewrite the code. So far my data looks identical to the bottom one (with updated data) except that the horizontal lines are not showing up in the legend. However, I need to make two legends as shown below but only have the Year part set up and am getting confused how to change both the name, line type and color of the lines while separating them into a separate legend from the Year Group.

Example of my data:

```<code># Groups:   Year [6]
Year  Month  Temp
<fct> <ord> <dbl>
1 2014  Mar    14.9
2 2014  Apr    16.6
3 2014  May    20.5
4 2014  Jun    22.0
5 2014  Jul    23.9
6 2014  Aug    24.3
7 2014  Sep    24.4
8 2014  Oct    22.1
9 2014  Dec    13.6
10 2015  Jan    11.5
# ... with 46 more rows
</code>```

My code so far:

```<code> ggplot(wq4, aes(x=Month,y=Temp, color = Year)) +
 geom_line(aes(color = Year, group = Year)) +
 labs(y = "Average Temperature (C)") +
 geom_hline(aes(yintercept = 5), color = "red", linetype="dashed") +
 geom_hline(aes(yintercept = 15), color = "dark green", linetype="dashed")
</code>```

答:
You can try using ggnewscale, first something with the same format as your data:

```<code>MTH = months(seq(as.Date("1910/1/1"), as.Date("1910/12/1"), "months"))
wq4 = data.frame(Year=factor(rep(2014:2018,each=12)),
Month=factor(rep(MTH,5),levels=MTH,ordered=TRUE),
Temp=sample(10:25,60,replace=TRUE))
</code>```

Before plotting, create a dataframe for intercepts:

```<code>library(ggnewscale)
library(ggplot2)

intercept_DF = data.frame(y=c(5,15),label=c("Temp1","Temp2"))

ggplot(wq4) +
 geom_line(aes(x=Month,y=Temp, color = Year,group=Year)) +
 labs(y = "Average Temperature (C)") +
 new_scale_color()+
 geom_hline(data=intercept_DF,aes(yintercept = y,col=label),linetype="dashed")+
scale_color_manual(name="Threhold",values=c("red","darkgreen"))
</code>```

Still figuring out how to order the two legends (if possible)

Title: How to make two legends using ggplot 2?

Body:
I am rather new to plotting graphs in R. I'm trying to create two legends similar to the picture below. The picture below is of data from the previous year and I'm updating it but need to rewrite the code. So far my data looks identical to the bottom one (with updated data) except that the horizontal lines are not showing up in the legend. However, I need to make two legends as shown below but only have the Year part set up and am getting confused how to change both the name, line type and color of the lines while separating them into a separate legend from the Year Group.

Example of my data:

# Groups:   Year [6]
Year  Month  Temp
<fct> <ord> <dbl>
1 2014  Mar    14.9
2 2014  Apr    16.6
3 2014  May    20.5
4 2014  Jun    22.0
5 2014  Jul    23.9
6 2014  Aug    24.3
7 2014  Sep    24.4
8 2014  Oct    22.1
9 2014  Dec    13.6
10 2015  Jan    11.5
# ... with 46 more rows

My code so far:

 ggplot(wq4, aes(x=Month,y=Temp, color = Year)) +
 geom_line(aes(color = Year, group = Year)) +
 labs(y = "Average Temperature (C)") +
 geom_hline(aes(yintercept = 5), color = "red", linetype="dashed") +
 geom_hline(aes(yintercept = 15), color = "dark green", linetype="dashed")

Body:
You can try using ggnewscale, first something with the same format as your data:

MTH = months(seq(as.Date("1910/1/1"), as.Date("1910/12/1"), "months"))
wq4 = data.frame(Year=factor(rep(2014:2018,each=12)),
Month=factor(rep(MTH,5),levels=MTH,ordered=TRUE),
Temp=sample(10:25,60,replace=TRUE))

Before plotting, create a dataframe for intercepts:

library(ggnewscale)
library(ggplot2)

intercept_DF = data.frame(y=c(5,15),label=c("Temp1","Temp2"))

ggplot(wq4) +
 geom_line(aes(x=Month,y=Temp, color = Year,group=Year)) +
 labs(y = "Average Temperature (C)") +
 new_scale_color()+
 geom_hline(data=intercept_DF,aes(yintercept = y,col=label),linetype="dashed")+
scale_color_manual(name="Threhold",values=c("red","darkgreen"))

Still figuring out how to order the two legends (if possible)


问:
JNA ClientToScreen?
Having issues figuring out how to use the ClientToScreen winapi function with JNA.

I'm still getting 0, 0 output for the coordinates of the window handle.
Am referencing this but im sure im not doing it right https://msdn.microsoft.com/en-us/library/windows/desktop/dd183434(v=vs.85).aspx

```<code>    public interface User32Ex extends W32APIOptions {
    User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
    boolean GetCursorPos(long[] lpPoint);
    WinDef.HWND WindowFromPoint(long point);
    boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
    boolean ClientToScreen(WinDef.HWND hWnd, int pt);
}

public void debug() throws InterruptedException {
    while (true) {
        long[] getPos = new long[1];
        User32Ex.instance.GetCursorPos(getPos);
        WinDef.HWND hwnd = User32Ex.instance.WindowFromPoint(getPos[0]);

        WinDef.RECT rect = new WinDef.RECT();
        User32Ex.instance.GetClientRect(hwnd, rect);
        User32Ex.instance.ClientToScreen(hwnd, rect.left);
        User32Ex.instance.ClientToScreen(hwnd, rect.right);

        System.out.println(rect.toRectangle().toString());
        Thread.sleep(1500);
    }
}
</code>```

答:
@technomage is right. You need to use WinDef.POINT instead of int in your ClientToScreen() rect parameter.

If anyone looking for a working solution for the question, it's below.
In every 3rd sec, it's logging the window inner client coordinates desktop position.

Explanation.

In the User32ForClientRect interface, we load user32.dll with JNA and define a few methods.
The reason behind we not using the already implemented User32 methods from the JNA interface is simple. The methods that we need in our case are not implemented in JNA.

Methods:

FindWindow - it's included in JNA

Retreives the window handle HWND

GetClientRect

Retreives the window widht, height. to rect.right, rect.bottom

ClientToScreen

Retreives the window inner client desktop position. Left/Top corner coordinates

Example:

```<code>package application.playground;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

import java.awt.*;

public class ClientRectExample {
    interface User32ForClientRect extends StdCallLibrary {
        User32ForClientRect INSTANCE = Native.loadLibrary("user32", User32ForClientRect.class,
                W32APIOptions.DEFAULT_OPTIONS);
        WinDef.HWND FindWindow(String lpClassName, String lpWindowName);
        boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
        boolean ClientToScreen(WinDef.HWND hWnd, WinDef.POINT lpPoint);
    }

    public static void main(String[] args) {
        while (true) {
            try {
                Rectangle rectangle = ClientRectExample.getClientRect("WindowName");
                System.out.println(rectangle);
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static Rectangle getClientRect(String startOfWindowName) {
        WinDef.HWND hWnd = User32ForClientRect.INSTANCE.FindWindow(null, startOfWindowName);
        WinDef.POINT getPos = new WinDef.POINT();
        WinDef.RECT rect = new WinDef.RECT();
        User32ForClientRect.INSTANCE.GetClientRect(hWnd, rect);
        User32ForClientRect.INSTANCE.ClientToScreen(hWnd, getPos);

        return new Rectangle(getPos.x, getPos.y, rect.right, rect.bottom);
    }
}
</code>```

ContentLicense: CC BY-SA 3.0

Title: JNA ClientToScreen?

Body:
Having issues figuring out how to use the ClientToScreen winapi function with JNA.

I'm still getting 0, 0 output for the coordinates of the window handle.
Am referencing this but im sure im not doing it right https://msdn.microsoft.com/en-us/library/windows/desktop/dd183434(v=vs.85).aspx

    public interface User32Ex extends W32APIOptions {
    User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
    boolean GetCursorPos(long[] lpPoint);
    WinDef.HWND WindowFromPoint(long point);
    boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
    boolean ClientToScreen(WinDef.HWND hWnd, int pt);
}

public void debug() throws InterruptedException {
    while (true) {
        long[] getPos = new long[1];
        User32Ex.instance.GetCursorPos(getPos);
        WinDef.HWND hwnd = User32Ex.instance.WindowFromPoint(getPos[0]);

        WinDef.RECT rect = new WinDef.RECT();
        User32Ex.instance.GetClientRect(hwnd, rect);
        User32Ex.instance.ClientToScreen(hwnd, rect.left);
        User32Ex.instance.ClientToScreen(hwnd, rect.right);

        System.out.println(rect.toRectangle().toString());
        Thread.sleep(1500);
    }
}

Body:
@technomage is right. You need to use WinDef.POINT instead of int in your ClientToScreen() rect parameter.

If anyone looking for a working solution for the question, it's below.
In every 3rd sec, it's logging the window inner client coordinates desktop position.

Explanation.

In the User32ForClientRect interface, we load user32.dll with JNA and define a few methods.
The reason behind we not using the already implemented User32 methods from the JNA interface is simple. The methods that we need in our case are not implemented in JNA.

Methods:

FindWindow - it's included in JNA

Retreives the window handle HWND

GetClientRect

Retreives the window widht, height. to rect.right, rect.bottom

ClientToScreen

Retreives the window inner client desktop position. Left/Top corner coordinates

Example:

package application.playground;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

import java.awt.*;

public class ClientRectExample {
    interface User32ForClientRect extends StdCallLibrary {
        User32ForClientRect INSTANCE = Native.loadLibrary("user32", User32ForClientRect.class,
                W32APIOptions.DEFAULT_OPTIONS);
        WinDef.HWND FindWindow(String lpClassName, String lpWindowName);
        boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
        boolean ClientToScreen(WinDef.HWND hWnd, WinDef.POINT lpPoint);
    }

    public static void main(String[] args) {
        while (true) {
            try {
                Rectangle rectangle = ClientRectExample.getClientRect("WindowName");
                System.out.println(rectangle);
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static Rectangle getClientRect(String startOfWindowName) {
        WinDef.HWND hWnd = User32ForClientRect.INSTANCE.FindWindow(null, startOfWindowName);
        WinDef.POINT getPos = new WinDef.POINT();
        WinDef.RECT rect = new WinDef.RECT();
        User32ForClientRect.INSTANCE.GetClientRect(hWnd, rect);
        User32ForClientRect.INSTANCE.ClientToScreen(hWnd, getPos);

        return new Rectangle(getPos.x, getPos.y, rect.right, rect.bottom);
    }
}


问:
no submodule mapping found in .gitmodules for path xx
I have tried a lot of different answers on stack but none of them work. I am trying to add a repository as a submodule which contains another submodule. So what I do is this:

```<code>git submodule add -b develop git@github.com:submoduleRepo
</code>```

The submodule is added to the repository and contains the folder of the submodule within it. However the folder is empty. So I follow up with this command:

```<code>git submodule update --init --recursive
</code>```

Which returns me nothing. If I go to the directory of the submodule cd submoduleRepo and then type git submodule, I get:

```<code>fatal: no submodule mapping found in .gitmodules for path 'src/app/nestedSubmoduleRepo'
</code>```

This is my .gitmodules of the main repo:

```<code>[submodule "submoduleRepo"]
    path = submoduleRepo
    url = git@github.com:submoduleRepo.git
    branch = develop
</code>```

And within submoduleRepo/.gitmodules:

```<code>[submodule ".\\src\\app\\nestedSubmoduleRepo"]
    path = .\\src\\app\\nestedSubmoduleRepo
    url = git@github.com:nestedSubmoduleRepo.git
</code>```

Why do I keep getting this error and is the directory not getting populated?

EDIT:

Once I've ran --init --recursive once it gives me the error:

```<code>fatal: No url found for submodule path 'submoduleRepo/src/app/nestedSubmoduleRepo' in .gitmodules
Failed to recurse into submodule path 'submoduleRepo'
</code>```

My git config:

```<code>[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
[remote "origin"]
    url = git@github.com:mainRepo.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[submodule "submoduleRepo"]
    url = git@github.com:submoduleRepo.git
    active = true
</code>```

答:
The problem is that your submodule repo is using backslashes in the .gitmodules file.  Git uses forward slashes for paths within the repository because they work across platforms (and backslashes do not), and it has no way of knowing whether your repository is intended to be cross platform or not.

You'll need to update the submodule repository to contain the proper entries in the file (and you should also drop the . path component as well).  Once you've committed that and updated the parent repository with the new commit, git submodule update --init --recursive should work properly.

Body:
I have tried a lot of different answers on stack but none of them work. I am trying to add a repository as a submodule which contains another submodule. So what I do is this:

git submodule add -b develop git@github.com:submoduleRepo

The submodule is added to the repository and contains the folder of the submodule within it. However the folder is empty. So I follow up with this command:

git submodule update --init --recursive

Which returns me nothing. If I go to the directory of the submodule cd submoduleRepo and then type git submodule, I get:

fatal: no submodule mapping found in .gitmodules for path 'src/app/nestedSubmoduleRepo'

This is my .gitmodules of the main repo:

[submodule "submoduleRepo"]
    path = submoduleRepo
    url = git@github.com:submoduleRepo.git
    branch = develop

And within submoduleRepo/.gitmodules:

[submodule ".\\src\\app\\nestedSubmoduleRepo"]
    path = .\\src\\app\\nestedSubmoduleRepo
    url = git@github.com:nestedSubmoduleRepo.git

Why do I keep getting this error and is the directory not getting populated?

EDIT:

Once I've ran --init --recursive once it gives me the error:

fatal: No url found for submodule path 'submoduleRepo/src/app/nestedSubmoduleRepo' in .gitmodules
Failed to recurse into submodule path 'submoduleRepo'

My git config:

[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
[remote "origin"]
    url = git@github.com:mainRepo.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[submodule "submoduleRepo"]
    url = git@github.com:submoduleRepo.git
    active = true


问:
Pythonanywhere error when accessing the homepage
I get the following error when I access my homepage (on Pythonanywhere). I believe all the settings are correct in the WSGI file. ImportError: No module named 'myproject' - even though the module is there. Is this something I have to define somewhere?

The error is as follows:

```<code>2020-02-19 02:25:26,696: Error running WSGI application
2020-02-19 02:25:26,697: ImportError: No module named 'myproject'
2020-02-19 02:25:26,697:   File "/var/www/user1_pythonanywhere_com_wsgi.py", line 16, in <module>
2020-02-19 02:25:26,697:     application = get_wsgi_application()
2020-02-19 02:25:26,697:
2020-02-19 02:25:26,697:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
2020-02-19 02:25:26,697:     django.setup(set_prefix=False)
2020-02-19 02:25:26,697:
2020-02-19 02:25:26,697:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/__init__.py", line 19, in setup
2020-02-19 02:25:26,698:     configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
2020-02-19 02:25:26,698:
2020-02-19 02:25:26,698:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/conf/__init__.py", line 79, in __getattr__
2020-02-19 02:25:26,698:     self._setup(name)
2020-02-19 02:25:26,698:
2020-02-19 02:25:26,698:   File "/home//.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/conf/__init__.py", line 66, in _setup
2020-02-19 02:25:26,698:     self._wrapped = Settings(settings_module)
2020-02-19 02:25:26,698:
2020-02-19 02:25:26,699:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/conf/__init__.py", line 157, in __init__
2020-02-19 02:25:26,699:     mod = importlib.import_module(self.SETTINGS_MODULE)
</code>```

答: I figured it out. It was an issue with the path. I dropped the app and re-created it from scratch. Worked like a charm!</p>

Body:
I get the following error when I access my homepage (on Pythonanywhere). I believe all the settings are correct in the WSGI file. ImportError: No module named 'myproject' - even though the module is there. Is this something I have to define somewhere?

The error is as follows:

2020-02-19 02:25:26,696: Error running WSGI application
2020-02-19 02:25:26,697: ImportError: No module named 'myproject'
2020-02-19 02:25:26,697:   File "/var/www/user1_pythonanywhere_com_wsgi.py", line 16, in <module>
2020-02-19 02:25:26,697:     application = get_wsgi_application()
2020-02-19 02:25:26,697:
2020-02-19 02:25:26,697:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
2020-02-19 02:25:26,697:     django.setup(set_prefix=False)
2020-02-19 02:25:26,697:
2020-02-19 02:25:26,697:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/__init__.py", line 19, in setup
2020-02-19 02:25:26,698:     configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
2020-02-19 02:25:26,698:
2020-02-19 02:25:26,698:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/conf/__init__.py", line 79, in __getattr__
2020-02-19 02:25:26,698:     self._setup(name)
2020-02-19 02:25:26,698:
2020-02-19 02:25:26,698:   File "/home//.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/conf/__init__.py", line 66, in _setup
2020-02-19 02:25:26,698:     self._wrapped = Settings(settings_module)
2020-02-19 02:25:26,698:
2020-02-19 02:25:26,699:   File "/home/user1/.virtualenvs/mysite-virtualenv/lib/python3.5/site-packages/django/conf/__init__.py", line 157, in __init__
2020-02-19 02:25:26,699:     mod = importlib.import_module(self.SETTINGS_MODULE)


问:
Regex to match quote with minimum number of words
I have the following text:

Attorney General William Barr said the volume of information
  compromised was “staggering” and the largest breach in U.S.
  history.“This theft not only caused significant financial damage to
  Equifax but invaded the privacy of many, millions of Americans and
  imposed substantial costs and burdens on them as they had to take
  measures to protect themselves from identity theft,” said Mr. Barr.

I want to match text within a quote however the quote must be a min of 5 words long otherwise it should be ignored.

Currently, I am using the following regex:

```<code>(?<=[\\“|\\"])[A-Za-z0-9\.\-][A-Za-z\s,:\\’]+(?=[\”|\"])
</code>```

However, this would include the quote “staggering”  which is only 1 word so it should be ignored.

I realize I could accomplish this by repeating this part of Regex 5 times:

```<code>[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+
</code>```

However, I am wondering if there is a shorter and more concise way to achieve this? Perhaps by forcing the \s in [] to appear at least 5 times?

Thanks

答:
You need to use the correct regex that matches your case.

The one in the code snippet bellow matches text within quotes 5 words long,

```<code>    Pattern pattern = Pattern.compile("“((\\b\\w+\\b)+.?( *)){5,}”", Pattern.DOTALL);

    String input = "Attorney General William Barr said the volume of "+
    "information compromised was “staggering” and the largest breach in"+
     "U.S. history.“This theft not only caused significant financial "+
     "damage to Equifax but invaded the privacy of many, millions of"+
     "Americans and imposed substantial costs and burdens on them as "+
     "they had to take measures to protect themselves from identity theft,” said Mr. Barr.";

    Matcher m = pattern.matcher(input);

    while (m.find()) {
      String s = m.group();
      System.out.print(s);
    }
</code>```

Note: You need to set a utf8 flag to compile those specific quote characters, '“' and '”'.
So instead of javac TheClass.java use javac -encoding utf8 TheClass.java!

Body:
I have the following text:

Attorney General William Barr said the volume of information
  compromised was “staggering” and the largest breach in U.S.
  history.“This theft not only caused significant financial damage to
  Equifax but invaded the privacy of many, millions of Americans and
  imposed substantial costs and burdens on them as they had to take
  measures to protect themselves from identity theft,” said Mr. Barr.

I want to match text within a quote however the quote must be a min of 5 words long otherwise it should be ignored.

Currently, I am using the following regex:

(?<=[\\“|\\"])[A-Za-z0-9\.\-][A-Za-z\s,:\\’]+(?=[\”|\"])

However, this would include the quote “staggering”  which is only 1 word so it should be ignored.

I realize I could accomplish this by repeating this part of Regex 5 times:

[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+

However, I am wondering if there is a shorter and more concise way to achieve this? Perhaps by forcing the \s in [] to appear at least 5 times?

Thanks

Body:
You need to use the correct regex that matches your case.

The one in the code snippet bellow matches text within quotes 5 words long,

    Pattern pattern = Pattern.compile("“((\\b\\w+\\b)+.?( *)){5,}”", Pattern.DOTALL);

    String input = "Attorney General William Barr said the volume of "+
    "information compromised was “staggering” and the largest breach in"+
     "U.S. history.“This theft not only caused significant financial "+
     "damage to Equifax but invaded the privacy of many, millions of"+
     "Americans and imposed substantial costs and burdens on them as "+
     "they had to take measures to protect themselves from identity theft,” said Mr. Barr.";

    Matcher m = pattern.matcher(input);

    while (m.find()) {
      String s = m.group();
      System.out.print(s);
    }

Note: You need to set a utf8 flag to compile those specific quote characters, '“' and '”'.
So instead of javac TheClass.java use javac -encoding utf8 TheClass.java!


问:
Problem with deleting entity from relational database
I am trying to write a method that would remove an entity from the table book that has a relation with entities from table comments. The idea is to remove all the records in comments while removing record in book.

Can someone help me with this? I don't know what is wrong, it is removing comments correctly but then error occurs. The method from service responsible for deleting, classes and message from Spring are below. Cheers

Error is as below:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find birski.bookstore.models.Comment with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find birski.bookstore.models.

Comment with id 1] with root cause

Method from service responsible for deleting entities

```<code>    public ResponseEntity<?> deleteBookDto(String bookTitle){
        return bookRepository.findByTitle(bookTitle).map(b ->{
            for (Comment comment : b.getComments()){
                commentRepository.delete(comment);
            }
            bookRepository.delete(b);
            return new ResponseEntity<>("Book titled: " + bookTitle + " was deleted!", HttpStatus.OK);
        }).orElseThrow(()-> new ResourceNotFoundException("Book titled: " + bookTitle + " have not been found."));
    }
</code>```

Book class

```<code>@Entity
@Table(name = "books", schema = "public")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "Title is required")
    private String title;

    @NotBlank(message = "Author is required")
    private String author;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Comment> comments = new HashSet<>();

    public Book() {
    }

    public Long getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Set<Comment> getComments() {
        return comments;
    }

    public void setComments(Set<Comment> comments) {
        this.comments = comments;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
</code>```

Comment class

```<code>@Entity
@Table(name = "comments", schema = "public")
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String author;

    @NotNull
    private String description;

    @NotNull
    private float rating;

    @NotNull
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date date;

    @ManyToOne//(cascade = CascadeType.ALL)
    private Book book;

    public Comment() {
    }

    public Long getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }
}
</code>```

答:
You have

```<code>@OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Comment> comments = new HashSet<>();
</code>```

as well as your code to explicitly delete() your comments. When Hibernate handles deleting the the book, it tries to delete the book's comments, but you have already deleted those comments from the database. You need one or the other.

Body:
I am trying to write a method that would remove an entity from the table book that has a relation with entities from table comments. The idea is to remove all the records in comments while removing record in book.

Can someone help me with this? I don't know what is wrong, it is removing comments correctly but then error occurs. The method from service responsible for deleting, classes and message from Spring are below. Cheers

Error is as below:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find birski.bookstore.models.Comment with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find birski.bookstore.models.

Comment with id 1] with root cause

Method from service responsible for deleting entities

    public ResponseEntity<?> deleteBookDto(String bookTitle){
        return bookRepository.findByTitle(bookTitle).map(b ->{
            for (Comment comment : b.getComments()){
                commentRepository.delete(comment);
            }
            bookRepository.delete(b);
            return new ResponseEntity<>("Book titled: " + bookTitle + " was deleted!", HttpStatus.OK);
        }).orElseThrow(()-> new ResourceNotFoundException("Book titled: " + bookTitle + " have not been found."));
    }

Book class

@Entity
@Table(name = "books", schema = "public")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "Title is required")
    private String title;

    @NotBlank(message = "Author is required")
    private String author;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Comment> comments = new HashSet<>();

    public Book() {
    }

    public Long getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Set<Comment> getComments() {
        return comments;
    }

    public void setComments(Set<Comment> comments) {
        this.comments = comments;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

Comment class

@Entity
@Table(name = "comments", schema = "public")
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String author;

    @NotNull
    private String description;

    @NotNull
    private float rating;

    @NotNull
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date date;

    @ManyToOne//(cascade = CascadeType.ALL)
    private Book book;

    public Comment() {
    }

    public Long getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }
}

Body:
You have

@OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Comment> comments = new HashSet<>();

as well as your code to explicitly delete() your comments. When Hibernate handles deleting the the book, it tries to delete the book's comments, but you have already deleted those comments from the database. You need one or the other.


问:
Using Lucene to work with graph data
Is there a way to use Lucene to work with graph data?

Example

One user has a relationship with many lucene documents (Document Connections)
One User has a relationship with other Users (User Connections [Graph])

If a user searches the Index, he gets back the documents that he has a relationship with. This is simple and straightforward.

What would be a way to get back the documents that the User Connections have a relationship with.

Indexing each document with all the user's that have a relationship with it in a user_id field is an approach. However when you query the index providing the User Connections for the user performing the search query size is unpredictable. Think of Users that have 1000's of User Connections. This will not scale.

It's almost like the User Connections and User Documents stored in a Graph DB can easily provide us the documents to search against but what is an effective way to communicate that to Lucene so it can only search against those documents for the given query. If any results are returned, this will guarantee that at least one or more of the User Connections has a relationship with the documents returned in the results.

答:
Apache Jena may be relevant here since it has some graph capabilities (SPARQL, RDF) and makes use of Lucene.

See Apache Jena Fuseki and Jena Text.

Title: Using Lucene to work with graph data


问:
How to rearrange numbers using SED (transposition)
I have a line:

```<code>The ID number for product is 721- 971-4321.`
</code>```

I want to swap the area code and exchange it for the number inside, like so: 971- 721-4321

Here is what I have:

```<code>17s/\([654]\)-\([817]\)/\2-\1/
</code>```

So the number is on line 17 in a .txt file. There is other stuff on the line but I want to only change the number.

Whenever I run the script nothing happens. Any advice how to fix this.

Body:
I have a line:

The ID number for product is 721- 971-4321.`

I want to swap the area code and exchange it for the number inside, like so: 971- 721-4321

Here is what I have:

17s/\([654]\)-\([817]\)/\2-\1/

So the number is on line 17 in a .txt file. There is other stuff on the line but I want to only change the number.

Whenever I run the script nothing happens. Any advice how to fix this.

Body:
This might work for you (GNU sed):

sed -E 's/([0-9]+-) ([0-9]+-)/\2 \1/' file


问:
One-way one-to-one relationship with EF Core
What I want to achieve, is have a model CommentsThread that can be attached to any other model that needs comments, be it Chapter, BlogPost, UserProfile, or what have you. Basically, the structure I need is

```<code>CommentsThread
  int ID

Chapter
  int ID
  int Thread FK(CommentsThread.ID)

BlogPost
  int ID
  int Thread FK(CommentsThread.ID)

UserProfile
  int ID
  int Thread FK(CommentsThread.ID)
</code>```

however I have no idea how to configure it properly in EF core, without having to add nullable references to Chapter, BlogPost and UserProfile to the CommentsThread model.

My code for CommentsThread is as follows:

public class CommentsThread
{
    [Key]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public ICollection<Comment> Comments { get; set; }
}
```

<p>And <code>Chapter</code>, omitting any irrelevant properties, is</p>

<pre class="lang-cs prettyprint-override"><code>public class Chapter
{
    [Key]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public CommentsThread CommentsThread { get; set; }
}
</code>```

With the following Fluent config (again, skipping the irrelevant bits):

builder.Entity<CommentsThread>()
    .HasMany(ct => ct.Comments)
    .WithOne()
    .OnDelete(DeleteBehavior.Cascade);

builder.Entity<Chapter>()
    .HasOne(c => c.CommentsThread)
    .WithOne()
    .OnDelete(DeleteBehavior.Cascade);
```

<p>On <code>dotnet ef migrations add X</code> it throws this output into the console.</p>

<hr>

<p><strong>Update:</strong></p>

<p>So, I tried explicitly adding <code>public int CommentsThreadId { get; set; }</code> to the <code>Chapter</code> and changing the config to</p>

```builder.Entity<Chapter>()
    .HasOne(c => c.CommentsThread)
    .WithOne()
    .HasForeignKey<Chapter>(c => c.CommentsThreadId)
    .OnDelete(DeleteBehavior.Cascade);
```

<p>That did make the migration go through, but failed on <code>database update</code> with</p>

```The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Chapters' and the index name 'IX_Chapters_CommentsThreadId'. The duplicate key value is (0).
The statement has been terminated.
```

答:
Your database migration error;

```<code>The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Chapters' and the index name 'IX_Chapters_CommentsThreadId'. The duplicate key value is (0).
The statement has been terminated.
</code>```

Is due to adding a non-null column to a table that already has data in it. If you want to force a CommentsThread to exist for each record type, you'll also need to write a migration script to insert these records for existing data.

Or just change the foreign key column type to int? so it will allow nulls.

Body:
What I want to achieve, is have a model CommentsThread that can be attached to any other model that needs comments, be it Chapter, BlogPost, UserProfile, or what have you. Basically, the structure I need is

CommentsThread
  int ID

Chapter
  int ID
  int Thread FK(CommentsThread.ID)

BlogPost
  int ID
  int Thread FK(CommentsThread.ID)

UserProfile
  int ID
  int Thread FK(CommentsThread.ID)

however I have no idea how to configure it properly in EF core, without having to add nullable references to Chapter, BlogPost and UserProfile to the CommentsThread model.

My code for CommentsThread is as follows:

public class CommentsThread
{
    [Key]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public ICollection<Comment> Comments { get; set; }
}

And Chapter, omitting any irrelevant properties, is

public class Chapter
{
    [Key]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public CommentsThread CommentsThread { get; set; }
}

With the following Fluent config (again, skipping the irrelevant bits):

builder.Entity<CommentsThread>()
    .HasMany(ct => ct.Comments)
    .WithOne()
    .OnDelete(DeleteBehavior.Cascade);

builder.Entity<Chapter>()
    .HasOne(c => c.CommentsThread)
    .WithOne()
    .OnDelete(DeleteBehavior.Cascade);

On dotnet ef migrations add X it throws this output into the console.

Update:

So, I tried explicitly adding public int CommentsThreadId { get; set; } to the Chapter and changing the config to

builder.Entity<Chapter>()
    .HasOne(c => c.CommentsThread)
    .WithOne()
    .HasForeignKey<Chapter>(c => c.CommentsThreadId)
    .OnDelete(DeleteBehavior.Cascade);

That did make the migration go through, but failed on database update with

The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Chapters' and the index name 'IX_Chapters_CommentsThreadId'. The duplicate key value is (0).
The statement has been terminated.

Body:
Your database migration error;

The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Chapters' and the index name 'IX_Chapters_CommentsThreadId'. The duplicate key value is (0).
The statement has been terminated.

Is due to adding a non-null column to a table that already has data in it. If you want to force a CommentsThread to exist for each record type, you'll also need to write a migration script to insert these records for existing data.

Or just change the foreign key column type to int? so it will allow nulls.


问:
How can I combine these two API's?
Trying to make it so that when a user deletes their account it deletes all their posts too. Eventually I'll have it delete everything related to them too.

```<code>router.route('/')
    .delete((req, res) => {
      let currentUser = req.user.dataValues;
      return service.removeUser(currentUser.uuid).then(removed => {
        res.json(removed);
      })
    })

router.route('/removeAllProds')
    .delete((req,res) => {
      let currentUser = req.user.dataValues;
      return service.removeAllUserProds(currentUser.uuid).then(removed => {
        res.json(removed);
      })
    })
</code>```

These are the functions being pulled

```<code>removeUser(userUuid) {
    return this.models.User.destroy({
      where: {
        uuid: userUuid
      }
    })
  }
removeAllUserProds(userUuid) {
    return this.models.Product.destroy({
      where: {
        sellerUuid: userUuid
      }
    })
  }
</code>```

答:
So if the user is deleted from database then all of associated/related to this user will be deleted as well. If yes, you need to turn your question into more detail, what database or ORM are you use.

Here is some example if you use mongodb, mysql/postgresql:

Mongoose(mongodb) you can use the pre 'remove' middleware

// create article schema
const articleSchema = new mongoose.Schema({
  title: {
    type: String,
  },
  content: {
    type: String,
  },
  author: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  }
});

// create user schema
const userSchema = new mongoose.Schema({
  username: {
    type: String,
    unique: true,
  },
});
// the below middleware will remove all article related to this user/author
userSchema.pre('remove', function(next) {
  this.model('Article').deleteMany({ author: this._id }, next);
});```
</div>
</div>
</p>

<p>You can read all the documentation regarding pre hooks here</p>

<ul>
<li>If you use SQL (MySql/PostgreSql) with Sequelize as ORM:</li>
</ul>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>  const User = sequelize.define('user', {
    username: {
      type: DataTypes.STRING,
    },
  });
  User.associate = models => {
    User.hasMany(models.Article, { onDelete: 'CASCADE' });
  };</code>```

At relational database they already provide a rule called ON DELETE CASCADE, which mean if you delete the parent record then any child records are also deleted. Here is a link for more detail example on sequelize.

Title: How can I combine these two API's?

Body:
Trying to make it so that when a user deletes their account it deletes all their posts too. Eventually I'll have it delete everything related to them too.

router.route('/')
    .delete((req, res) => {
      let currentUser = req.user.dataValues;
      return service.removeUser(currentUser.uuid).then(removed => {
        res.json(removed);
      })
    })

router.route('/removeAllProds')
    .delete((req,res) => {
      let currentUser = req.user.dataValues;
      return service.removeAllUserProds(currentUser.uuid).then(removed => {
        res.json(removed);
      })
    })

These are the functions being pulled

removeUser(userUuid) {
    return this.models.User.destroy({
      where: {
        uuid: userUuid
      }
    })
  }
removeAllUserProds(userUuid) {
    return this.models.Product.destroy({
      where: {
        sellerUuid: userUuid
      }
    })
  }

Body:
So if the user is deleted from database then all of associated/related to this user will be deleted as well. If yes, you need to turn your question into more detail, what database or ORM are you use.

Here is some example if you use mongodb, mysql/postgresql:

Mongoose(mongodb) you can use the pre 'remove' middleware

// create article schema
const articleSchema = new mongoose.Schema({
  title: {
    type: String,
  },
  content: {
    type: String,
  },
  author: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  }
});

// create user schema
const userSchema = new mongoose.Schema({
  username: {
    type: String,
    unique: true,
  },
});
// the below middleware will remove all article related to this user/author
userSchema.pre('remove', function(next) {
  this.model('Article').deleteMany({ author: this._id }, next);
});

You can read all the documentation regarding pre hooks here

If you use SQL (MySql/PostgreSql) with Sequelize as ORM:

  const User = sequelize.define('user', {
    username: {
      type: DataTypes.STRING,
    },
  });
  User.associate = models => {
    User.hasMany(models.Article, { onDelete: 'CASCADE' });
  };

At relational database they already provide a rule called ON DELETE CASCADE, which mean if you delete the parent record then any child records are also deleted. Here is a link for more detail example on sequelize.


问:
Finding the cumulative sum of a list
I'm trying to create a function that takes a list as an argument and then gives back a new list with the cumulative sum of that list. For example:

```<code>l = [1, 7, -3, 9, -2]
</code>```

would become:

```<code>[1, 8, 5, 14, 12]
</code>```

I am also trying to use a for loop for this function.

Title: Finding the cumulative sum of a list

Body:
I'm trying to create a function that takes a list as an argument and then gives back a new list with the cumulative sum of that list. For example:

l = [1, 7, -3, 9, -2]

would become:

[1, 8, 5, 14, 12]

I am also trying to use a for loop for this function.

Body:
Python makes this super easy:

>>> l = [1, 7, -3, 9, -2]
>>> [ sum(l[:n+1]) for n in range(len(l)) ]
[1, 8, 5, 14, 12]


问:
Changing x86 to x64 affects my LNK1168 Error
So I created a code in C++ using visual studio and I was learning about making classes and using methods/functions. The program was working fine until I wrote the  using namespace std; and suddenly trying to run my code I got a LNK1168 error and I tried everything to fix it.

I made sure that no tasks were running, and I saved it and closed it and opened it back up to run it again and still no matter what I did, the LNK1168 error pops back up.

I then switched from debugging x86 to debugging x64 and my code works normally with the x64.

Does this matter? If so why, if not then what should I do?

```<code>#include<iostream>

// did not include the using namespace std; because that's when my issue started
// not sure if it had something to do with it

class Player
{
public:
    int x, y;
    int speed;

void movin(int xa, int ya)
{
    x += xa * speed;
    y += ya * speed;
}

};

int main()
{

    Player player;

    player.movin(1, 1);

    std::cout << "apples are tasty";  // this is to make sure my code prints something

    std::cin.get();

    return 0;
}

</code>```

I tried looking up youtube videos but nothing helps! Oddly enough the x64 works but not the usual x86? Does this affect my code or how I compile my code? Would it make things run slower? I am confused.
I tried looking at the Windows Help site after clicking the error and nothing helps. Does anyone know?

答: LNK1168 Means your executable is still running when you try to compile the code. Close the app, and then compile.</p>

Body:
So I created a code in C++ using visual studio and I was learning about making classes and using methods/functions. The program was working fine until I wrote the  using namespace std; and suddenly trying to run my code I got a LNK1168 error and I tried everything to fix it.

I made sure that no tasks were running, and I saved it and closed it and opened it back up to run it again and still no matter what I did, the LNK1168 error pops back up.

I then switched from debugging x86 to debugging x64 and my code works normally with the x64.

Does this matter? If so why, if not then what should I do?

#include<iostream>

// did not include the using namespace std; because that's when my issue started
// not sure if it had something to do with it

class Player
{
public:
    int x, y;
    int speed;

void movin(int xa, int ya)
{
    x += xa * speed;
    y += ya * speed;
}

};

int main()
{

    Player player;

    player.movin(1, 1);

    std::cout << "apples are tasty";  // this is to make sure my code prints something

    std::cin.get();

    return 0;
}

I tried looking up youtube videos but nothing helps! Oddly enough the x64 works but not the usual x86? Does this affect my code or how I compile my code? Would it make things run slower? I am confused.
I tried looking at the Windows Help site after clicking the error and nothing helps. Does anyone know?


问:
Why can subscribe be called on subject even after it is completed?
As per most of the blogs we don't need to explicitly unsubscribe the subjects once we call complete. I tried to subscribe the subject after calling complete on it. The complete call back was still executed.

```<code>let s = new Subject();
s.complete();

s.subscribe(
  () => {
    console.log("next");
  },
  () => {},
  () => {
    console.log("complete");
  }
);
</code>```

Output: complete

Why subscribing to subject is allowed after it is completed?

答:
What happens in this case is that first, a 'complete' notification is dispatched, and immediately afterwards, the subscription is unsubbed. So it still holds that you don't have to unsub manually.

If you are wondering what's the use of subscribing in the first place, you can think of an example where we apply isEmpty operator to the subject, and do something depending on the value nexted by this operator.

Body:
As per most of the blogs we don't need to explicitly unsubscribe the subjects once we call complete. I tried to subscribe the subject after calling complete on it. The complete call back was still executed.

let s = new Subject();
s.complete();

s.subscribe(
  () => {
    console.log("next");
  },
  () => {},
  () => {
    console.log("complete");
  }
);

Output: complete

Why subscribing to subject is allowed after it is completed?


问:
MySQL: help designing tables for storing variable numbers of identical form lists
i'm ingesting JSON dumps of a client's form, which itself contains data from sub-forms.  so i have fields of data like 'username' and then blocks of form data that may or may not contain data.  the portion that concerns me looks like this:

```<code>"instruction1"=>true,
"instructionID1"=>1234,
"instructionInfo1"=>"blah blah",
"instructionReqs1"=>"bleh bleh",
"instructionDue1"=>1970-01-01,
...
</code>```

this section repeats 14 more times (eg. 'instruction2'=>false, &c).  each block either has content or it doesn't, but each record has 15 total as part of the overall record to be stored.  i am stumped as to how best to store this.  right now, trying to just blunt-force-trauma this thing gives me this error when i try to add the 15th block:

Failed to add recordRow size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

and since i don't want to clone this whole thing (and everything else) over to a new instance of MariaDB (unless it is absolutely the only way out of this), the innodb_page_size=64k fix isn't viable.

i can't help but stare at this and say "this chunk should be a table", but if i made a table for it, how it would be structured to only store information, not empty fields (eg. 'instruction1xxx' thru 'instruction6xxx' and nothing beyond because they're empty), and then reference this back to the parent record in a way that i can retrieve it all to a dashboard.

*huff* *puff* *wheeze*

i have perused other responses to vaguely similar questions and MongoDB is not an option here because of the rest of the production stack itegration.

i hope this makes sense and i can get some clear eyes on this.  let me know if you need something more to clarify.

TIA.

答:
Use a simple key-value table.

```<code>CREATE TABLE formdata (
    client_id INT(11), // foreign key to client table
    name VARCHAR(128),
    value VARCHAR(1024)
);
</code>```

Then each item in the JSON would be a row in the table.

```<code>client_id   name            value
1           instruction1    true
1           instructionID1  1234
1           instructionInfo1 blah blah
...
</code>```

Body:
i'm ingesting JSON dumps of a client's form, which itself contains data from sub-forms.  so i have fields of data like 'username' and then blocks of form data that may or may not contain data.  the portion that concerns me looks like this:

"instruction1"=>true,
"instructionID1"=>1234,
"instructionInfo1"=>"blah blah",
"instructionReqs1"=>"bleh bleh",
"instructionDue1"=>1970-01-01,
...

this section repeats 14 more times (eg. 'instruction2'=>false, &c).  each block either has content or it doesn't, but each record has 15 total as part of the overall record to be stored.  i am stumped as to how best to store this.  right now, trying to just blunt-force-trauma this thing gives me this error when i try to add the 15th block:

Failed to add recordRow size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

and since i don't want to clone this whole thing (and everything else) over to a new instance of MariaDB (unless it is absolutely the only way out of this), the innodb_page_size=64k fix isn't viable.

i can't help but stare at this and say "this chunk should be a table", but if i made a table for it, how it would be structured to only store information, not empty fields (eg. 'instruction1xxx' thru 'instruction6xxx' and nothing beyond because they're empty), and then reference this back to the parent record in a way that i can retrieve it all to a dashboard.

*huff* *puff* *wheeze*

i have perused other responses to vaguely similar questions and MongoDB is not an option here because of the rest of the production stack itegration.

i hope this makes sense and i can get some clear eyes on this.  let me know if you need something more to clarify.

TIA.

Body:
Use a simple key-value table.

CREATE TABLE formdata (
    client_id INT(11), // foreign key to client table
    name VARCHAR(128),
    value VARCHAR(1024)
);

Then each item in the JSON would be a row in the table.

client_id   name            value
1           instruction1    true
1           instructionID1  1234
1           instructionInfo1 blah blah
...


问:
Java - Why is the whitespace being read in as a word?
I am attempting to read in a .txt file and print out the top twenty most common words and the top twenty least common words. However, whitespace appears as a word when it should not be counted as one. As I show in the Output, the whitespace appears as the second most common word, when it should not.
Here is my code.

```<code>public class WordFreqCount {

    public static void main(String[] args) throws IOException {

        HashMap<String, Integer> frequencyMap = new HashMap<String, Integer>();

        FileReader bookFile = new FileReader("book.txt");
        Scanner s = new Scanner(new FileReader("book.txt"));

        while(s.hasNext()) {
            String line = s.nextLine();
            line.trim();
            String[] words = line.split("\\W+");
            for (int i = 0; i < words.length; i ++) {

                if (frequencyMap.containsKey(words[i])) {
                    frequencyMap.replace(words[i], frequencyMap.get(words[i]) + 1);
                }
                else {
                    frequencyMap.put(words[i], 1);
                }
            }
        }
        s.close();

        List<Entry<String,Integer>> list = sortByValue(frequencyMap);

        System.out.println("Top 20 Most Appeared Words:");

        int counter1 = 1;
        List<Map.Entry<String, Integer>> topTwenty = list.subList(0, 20);
        for(Map.Entry<String, Integer> word : topTwenty) {
            System.out.println("(" + counter1 + "): " + word.getKey() + " --> " + word.getValue());
            counter1 += 1;
        }

        System.out.println();
        System.out.println("Top 20 Least Appeared Words:");

        int counter2 = 1;
        Collections.reverse(list);
        List<Map.Entry<String, Integer>> bottomTwenty = list.subList(0, 20);
        for(Map.Entry<String, Integer> word : bottomTwenty) {
            System.out.println("(" + counter2 + "): " + word.getKey() + " --> " + word.getValue());
            counter2 += 1;
        }
    }
}
</code>```

And the Output of my code is

```<code>(1): the --> 5426
(2):  --> 4986
(3): I --> 3038
(4): and --> 2887
(5): to --> 2788
(6): of --> 2733
(7): a --> 2595
(8): in --> 1747
(9): that --> 1664
(10): was --> 1393
(11): it --> 1303
(12): you --> 1283
(13): he --> 1168
(14): is --> 1131
(15): his --> 1103
(16): have --> 908
(17): my --> 907
(18): with --> 849
(19): had --> 821
(20): as --> 780

Top 20 Least Appeared Words:
(1): rival --> 1
(2): category --> 1
(3): arguments --> 1
(4): Bought --> 1
(5): billycock --> 1
(6): incoherent --> 1
(7): hail --> 1
(8): idle --> 1
(9): illustrious --> 1
(10): terminated --> 1
(11): Apaches --> 1
(12): topped --> 1
(13): laudanum --> 1
(14): filthy --> 1
(15): drama --> 1
(16): tune --> 1
(17): geology --> 1
(18): Mademoiselle --> 1
(19): balls --> 1
(20): Atkinson --> 1
</code>```

It was my understanding that using line.split("\W+") would parse the sentences to make sure nothing like whitespace, commas, etc. were counted in as words or within words. Am I missing something here?

A small portion of book.txt file

===========================================================================

```<code>almost no restrictions whatsoever.  You may copy it, give it away or
re-use it under the terms of the Project Gutenberg License included
with this eBook or online at www.gutenberg.net

Title: The Adventures of Sherlock Holmes

Author: Arthur Conan Doyle

Posting Date: April 18, 2011 [EBook #1661]
First Posted: November 29, 2002

Language: English

*** START OF THIS PROJECT GUTENBERG EBOOK THE ADVENTURES OF SHERLOCK HOLMES ***

Produced by an anonymous Project Gutenberg volunteer and Jose Menendez

THE ADVENTURES OF SHERLOCK HOLMES

by

SIR ARTHUR CONAN DOYLE

   I. A Scandal in Bohemia
  II. The Red-headed League
 III. A Case of Identity
  IV. The Boscombe Valley Mystery
   V. The Five Orange Pips
  VI. The Man with the Twisted Lip
 VII. The Adventure of the Blue Carbuncle
VIII. The Adventure of the Speckled Band
  IX. The Adventure of the Engineer's Thumb
   X. The Adventure of the Noble Bachelor
  XI. The Adventure of the Beryl Coronet
 XII. The Adventure of the Copper Beeches

ADVENTURE I. A SCANDAL IN BOHEMIA

I.

To Sherlock Holmes she is always THE woman. I have seldom heard
him mention her under any other name. In his eyes she eclipses
and predominates the whole of her sex. It was not that he felt
any emotion akin to love for Irene Adler. All emotions, and that
one particularly, were abhorrent to his cold, precise but
admirably balanced mind. He was, I take it, the most perfect
reasoning and observing machine that the world has seen, but as a
lover he would have placed himself in a false position. He never
spoke of the softer passions, save with a gibe and a sneer. They
were admirable things for the observer--excellent for drawing the
veil from men's motives and actions. But for the trained reasoner
to admit such intrusions into his own delicate and finely
adjusted temperament was to introduce a distracting factor which
might throw a doubt upon all his mental results. Grit in a
sensitive instrument, or a crack in one of his own high-power
lenses, would not be more disturbing than a strong emotion in a
nature such as his. And yet there was but one woman to him, and
that woman was the late Irene Adler, of dubious and questionable
memory.

I had seen little of Holmes lately. My marriage had drifted us
away from each other. My own complete happiness, and the
home-centred interests which rise up around the man who first
finds himself master of his own establishment, were sufficient to
absorb all my attention, while Holmes, who loathed every form of
society with his whole Bohemian soul, remained in our lodgings in
Baker Street, buried among his old books, and alternating from
week to week between cocaine and ambition, the drowsiness of the
drug, and the fierce energy of his own keen nature. He was still,
as ever, deeply attracted by the study of crime, and occupied his
immense faculties and extraordinary powers of observation in
following out those clues, and clearing up those mysteries which
had been abandoned as hopeless by the official police. From time
to time I heard some vague account of his doings: of his summons
to Odessa in the case of the Trepoff murder, of his clearing up
of the singular tragedy of the Atkinson brothers at Trincomalee,
and finally of the mission which he had accomplished so
delicately and successfully for the reigning family of Holland.
Beyond these signs of his activity, however, which I merely
shared with all the readers of the daily press, I knew little of
my former friend and companion.```

```

答:
Are there blank lines in the text file? "".split("\\W+") will return an array with one blank string element (i.e. {""}). Try this at the start of the while loop:

```<code>String line = s.nextLine().trim();
if (line.isEmpty()) {
    continue;
}
</code>```

Body:
I am attempting to read in a .txt file and print out the top twenty most common words and the top twenty least common words. However, whitespace appears as a word when it should not be counted as one. As I show in the Output, the whitespace appears as the second most common word, when it should not.
Here is my code.

public class WordFreqCount {

    public static void main(String[] args) throws IOException {

        HashMap<String, Integer> frequencyMap = new HashMap<String, Integer>();

        FileReader bookFile = new FileReader("book.txt");
        Scanner s = new Scanner(new FileReader("book.txt"));

        while(s.hasNext()) {
            String line = s.nextLine();
            line.trim();
            String[] words = line.split("\\W+");
            for (int i = 0; i < words.length; i ++) {

                if (frequencyMap.containsKey(words[i])) {
                    frequencyMap.replace(words[i], frequencyMap.get(words[i]) + 1);
                }
                else {
                    frequencyMap.put(words[i], 1);
                }
            }
        }
        s.close();

        List<Entry<String,Integer>> list = sortByValue(frequencyMap);

        System.out.println("Top 20 Most Appeared Words:");

        int counter1 = 1;
        List<Map.Entry<String, Integer>> topTwenty = list.subList(0, 20);
        for(Map.Entry<String, Integer> word : topTwenty) {
            System.out.println("(" + counter1 + "): " + word.getKey() + " --> " + word.getValue());
            counter1 += 1;
        }

        System.out.println();
        System.out.println("Top 20 Least Appeared Words:");

        int counter2 = 1;
        Collections.reverse(list);
        List<Map.Entry<String, Integer>> bottomTwenty = list.subList(0, 20);
        for(Map.Entry<String, Integer> word : bottomTwenty) {
            System.out.println("(" + counter2 + "): " + word.getKey() + " --> " + word.getValue());
            counter2 += 1;
        }
    }
}

And the Output of my code is

(1): the --> 5426
(2):  --> 4986
(3): I --> 3038
(4): and --> 2887
(5): to --> 2788
(6): of --> 2733
(7): a --> 2595
(8): in --> 1747
(9): that --> 1664
(10): was --> 1393
(11): it --> 1303
(12): you --> 1283
(13): he --> 1168
(14): is --> 1131
(15): his --> 1103
(16): have --> 908
(17): my --> 907
(18): with --> 849
(19): had --> 821
(20): as --> 780

Top 20 Least Appeared Words:
(1): rival --> 1
(2): category --> 1
(3): arguments --> 1
(4): Bought --> 1
(5): billycock --> 1
(6): incoherent --> 1
(7): hail --> 1
(8): idle --> 1
(9): illustrious --> 1
(10): terminated --> 1
(11): Apaches --> 1
(12): topped --> 1
(13): laudanum --> 1
(14): filthy --> 1
(15): drama --> 1
(16): tune --> 1
(17): geology --> 1
(18): Mademoiselle --> 1
(19): balls --> 1
(20): Atkinson --> 1

It was my understanding that using line.split("\W+") would parse the sentences to make sure nothing like whitespace, commas, etc. were counted in as words or within words. Am I missing something here?

A small portion of book.txt file

===========================================================================

almost no restrictions whatsoever.  You may copy it, give it away or
re-use it under the terms of the Project Gutenberg License included
with this eBook or online at www.gutenberg.net

Title: The Adventures of Sherlock Holmes

Author: Arthur Conan Doyle

Posting Date: April 18, 2011 [EBook #1661]
First Posted: November 29, 2002

Language: English

*** START OF THIS PROJECT GUTENBERG EBOOK THE ADVENTURES OF SHERLOCK HOLMES ***

Produced by an anonymous Project Gutenberg volunteer and Jose Menendez

THE ADVENTURES OF SHERLOCK HOLMES

by

SIR ARTHUR CONAN DOYLE

   I. A Scandal in Bohemia
  II. The Red-headed League
 III. A Case of Identity
  IV. The Boscombe Valley Mystery
   V. The Five Orange Pips
  VI. The Man with the Twisted Lip
 VII. The Adventure of the Blue Carbuncle
VIII. The Adventure of the Speckled Band
  IX. The Adventure of the Engineer's Thumb
   X. The Adventure of the Noble Bachelor
  XI. The Adventure of the Beryl Coronet
 XII. The Adventure of the Copper Beeches

ADVENTURE I. A SCANDAL IN BOHEMIA

I.

To Sherlock Holmes she is always THE woman. I have seldom heard
him mention her under any other name. In his eyes she eclipses
and predominates the whole of her sex. It was not that he felt
any emotion akin to love for Irene Adler. All emotions, and that
one particularly, were abhorrent to his cold, precise but
admirably balanced mind. He was, I take it, the most perfect
reasoning and observing machine that the world has seen, but as a
lover he would have placed himself in a false position. He never
spoke of the softer passions, save with a gibe and a sneer. They
were admirable things for the observer--excellent for drawing the
veil from men's motives and actions. But for the trained reasoner
to admit such intrusions into his own delicate and finely
adjusted temperament was to introduce a distracting factor which
might throw a doubt upon all his mental results. Grit in a
sensitive instrument, or a crack in one of his own high-power
lenses, would not be more disturbing than a strong emotion in a
nature such as his. And yet there was but one woman to him, and
that woman was the late Irene Adler, of dubious and questionable
memory.

I had seen little of Holmes lately. My marriage had drifted us
away from each other. My own complete happiness, and the
home-centred interests which rise up around the man who first
finds himself master of his own establishment, were sufficient to
absorb all my attention, while Holmes, who loathed every form of
society with his whole Bohemian soul, remained in our lodgings in
Baker Street, buried among his old books, and alternating from
week to week between cocaine and ambition, the drowsiness of the
drug, and the fierce energy of his own keen nature. He was still,
as ever, deeply attracted by the study of crime, and occupied his
immense faculties and extraordinary powers of observation in
following out those clues, and clearing up those mysteries which
had been abandoned as hopeless by the official police. From time
to time I heard some vague account of his doings: of his summons
to Odessa in the case of the Trepoff murder, of his clearing up
of the singular tragedy of the Atkinson brothers at Trincomalee,
and finally of the mission which he had accomplished so
delicately and successfully for the reigning family of Holland.
Beyond these signs of his activity, however, which I merely
shared with all the readers of the daily press, I knew little of
my former friend and companion.```

Body:
Are there blank lines in the text file? "".split("\\W+") will return an array with one blank string element (i.e. {""}). Try this at the start of the while loop:

String line = s.nextLine().trim();
if (line.isEmpty()) {
    continue;
}


问:
Is there a robust way to register dependencies in ASP.NET Core 3.1 beside adding everything into Startup class?
I have an ASP.NET Core 3.1 project. Typically, I register any dependency using the ConfigureServices() method in the Startup.cs class.

But, I find myself having to register lots of dependencies and the ConfigureServices() looks huge! I know I can probably create an extension method of a static method and call it from the ConfigureService()` class, but wondering if there is a better way.

If there a way to register dependencies in the IoC container without having to define them one at a time like this

```<code>services.AddScoped<Interface, Class>();
.... 200 lines later
services.AddScoped<ISettings, Settings>()
</code>```

答:
Create a custom attribute (called AutoBindAttribute)

```<code>public class AutoBindAttribute : Attribute
{
}
</code>```

Use it like bellow (Decorate all the implementations that you want to automatically bind with [AutroBind])

```<code>public interface IMyClass {}

[AutoBind]
public class MyClass : IMyClass {}
</code>```

Now create an extention method for IServiceCollection

```<code>public static class ServiceCollectionExtensions
{
    public static void AutoBind(this IServiceCollection source, params Assembly[] assemblies)
    {
       source.Scan(scan => scan.FromAssemblies(assemblies)
        .AddClasses(classes => classes.WithAttribute<AutoBindAttribute>())
        .AsImplementedInterfaces()
        .WithTransientLifetime();
    }
}
</code>```

Now call it in Startup.cs

```<code>public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AutoBind(typeof(Startup).Assembly);
    }

}
</code>```

Note: You can improve the ServiceCollectionExtentions class to support all scopes such as singleton, etc. This example shows only for Transient lifetime.

Enjoy!!!

Body:
I have an ASP.NET Core 3.1 project. Typically, I register any dependency using the ConfigureServices() method in the Startup.cs class.

But, I find myself having to register lots of dependencies and the ConfigureServices() looks huge! I know I can probably create an extension method of a static method and call it from the ConfigureService()` class, but wondering if there is a better way.

If there a way to register dependencies in the IoC container without having to define them one at a time like this

services.AddScoped<Interface, Class>();
.... 200 lines later
services.AddScoped<ISettings, Settings>()

Body:
Create a custom attribute (called AutoBindAttribute)

public class AutoBindAttribute : Attribute
{
}

Use it like bellow (Decorate all the implementations that you want to automatically bind with [AutroBind])

public interface IMyClass {}

[AutoBind]
public class MyClass : IMyClass {}

Now create an extention method for IServiceCollection

public static class ServiceCollectionExtensions
{
    public static void AutoBind(this IServiceCollection source, params Assembly[] assemblies)
    {
       source.Scan(scan => scan.FromAssemblies(assemblies)
        .AddClasses(classes => classes.WithAttribute<AutoBindAttribute>())
        .AsImplementedInterfaces()
        .WithTransientLifetime();
    }
}

Now call it in Startup.cs

public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AutoBind(typeof(Startup).Assembly);
    }

}

Note: You can improve the ServiceCollectionExtentions class to support all scopes such as singleton, etc. This example shows only for Transient lifetime.

Enjoy!!!


问:
ASP.NET Force IE8 to use IE7 or IE8 Compatability View
I've tried the following and all it does is change the Document Mode, not the Browser Mode:

```<code><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">

<meta http-equiv="X-UA-Compatible" content="IE=7">
</code>```

My particluar page only works when the browser mode is either IE7 or IE8 Compat View.

答:
The code you posted should work.

Please ensure the following:

The meta tag is right at the top of the header, as first element after the <title></title>.

Restart IE and open your page without manually setting the Browser- or Document Mode from the Developer Tools. Setting these manually can overwrite IE's behavior and causes it to ignore the compatibility tag.

Body:
I've tried the following and all it does is change the Document Mode, not the Browser Mode:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">

<meta http-equiv="X-UA-Compatible" content="IE=7">

My particluar page only works when the browser mode is either IE7 or IE8 Compat View.


问:
ActiveRecord bulk insert with has_one
Did you ever solved a problem of bulk insert of records with nested association?
(with rails insert_all or with the import gem)
example:

```<code>Dog.import!(array_of_dogs)
</code>```

and

```<code>Dog.insert_all(array_of_dogs)
</code>```

will not work if a Dog  has owner association as

```<code>has_one :owner, class_name: Person
</code>```

and expecting to persist all dogs and all their owners.

答:
You have two possibilitys.

You remove all constraints and insert all data and add the constraint at the end. This works because at the time of the backup all constraints worked and will do so after the recovery

you can only insert one table at a time, so you make an ER Model of your database, look which tables have to be created first so that all Tables that are in the hierarchy above can be created with a partner table that is already created withpout. And so on till you reach the end. the ER Model is not absolutely needed, but in big databases with lots of tables, it helps to keep order and with the right program you can move  teh tables around to find the right recovery order.

Title: ActiveRecord bulk insert with has_one

Body:
Did you ever solved a problem of bulk insert of records with nested association?
(with rails insert_all or with the import gem)
example:

Dog.import!(array_of_dogs)

and

Dog.insert_all(array_of_dogs)

will not work if a Dog  has owner association as

has_one :owner, class_name: Person

and expecting to persist all dogs and all their owners.