问:
Permission denied mounting an existing volume (without sudo)
Following setup:

I am a username on a machine. I am in the docker group such that I can run docker, which is installed on that machine.

I'm desperately trying to run jupyter/datascience-notebook on this machine but the problem is I cannot safe files there because the user does not seem to have access rights to the mounted directory.

It is supposed to work like this:

docker run -it --rm -p 8888:8888 -v ~/workspaces:/home/jovyan/work/ -e NB_UID=$(id -u) -e NB_GID=$(id -g) -e GRANT_SUDO=yes jupyter/datascience-notebook
```

<p>but it does not because I do not have <code>sudo</code> rights.</p>

<pre class="lang-sh prettyprint-override"><code>$ docker run -it --rm -p 8888:8888 -v ~/workspaces:/home/jovyan/work/ -e NB_UID=$(id -u) -e NB_GID=$(id -g) -e GRANT_SUDO=yes jupyter/datascience-notebook
Container must be run as root to set $NB_UID
Container must be run as root to set $NB_GID
Container must be run as root to grant sudo permissions
</code>```

I was planning to play around with a Dockerfile so I started to write this:

FROM jupyter/datascience-notebook

# Use user root
USER root

RUN ls -la ~/
RUN chown -R jovyan:users ~/.local
RUN chmod -R 1777 ~/.local
RUN ls -la ~/
```

<p>And here is the reason why: This little helper script below is supposed to create the image <code>test-image</code> and run it afterwards. </p>

<pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python
import os
import subprocess
from notebook.auth import passwd

cmd = 'docker run -it --rm -p 8888:8888 ' \
    '-v ~/workspaces:/home/jovyan/work ' \
    '-v ~/datasets:/home/jovyan/data ' \
    '-e NB_UID=$(id -u) -e NB_GID=$(id -g) -e GRANT_SUDO=yes ' \
    'test-image start.sh jupyter lab ' \
    '--NotebookApp.token=\'\' '

print('Running {}'.format(cmd))

subprocess.call('docker build --rm -t test-image .', shell=True)
subprocess.call(cmd, shell=True)
</code>```

For reasons I do not understand I get the following output:

```<code>...
Step 14/16 : RUN ls -la ~/
 ---> Running in ef30926edc1a
total 44
drwsrwsr-x 12 jovyan users 4096 Feb 22 12:59 .
drwxr-xr-x 12 root   root  4096 Feb 22 12:59 ..
-rw-rw-r--  1 jovyan users  220 Aug 31  2015 .bash_logout
-rw-rw-r--  1 jovyan users 3771 Aug 31  2015 .bashrc
drwsrwsr-x  3 jovyan users 4096 Feb 20 11:41 .cache
drwsrwsr-x  3 jovyan users 4096 Feb 20 09:29 .conda
drwsrwsr-x  3 jovyan users 4096 Feb 20 11:41 .config
drwxrwsrwt 11 jovyan users 4096 Feb 22 12:59 .local
-rw-rw-r--  1 jovyan users  655 May 16  2017 .profile
drwsrwsr-x  2 jovyan users 4096 Feb 20 09:28 work
drwsrwsr-x  3 jovyan users 4096 Feb 20 09:38 .yarn
 ---> 2de66bf593f3
Removing intermediate container ef30926edc1a
Step 15/16 : RUN ls -la ~/.local/share
...
Set username to: jovyan
usermod: no changes
Set jovyan UID to: 1006
Set jovyan GID to: 1006
Granting jovyan sudo access and appending /opt/conda/bin to sudo PATH
Executing the command: jupyter lab --NotebookApp.token=
Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/site-packages/traitlets/traitlets.py", line 528, in get
    value = obj._trait_values[self.name]
KeyError: 'runtime_dir'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/conda/bin/jupyter-lab", line 6, in <module>
    sys.exit(jupyterlab.labapp.main())
  File "/opt/conda/lib/python3.6/site-packages/jupyter_core/application.py", line 266, in launch_instance
    return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/traitlets/config/application.py", line 657, in launch_instance
    app.initialize(argv)
  File "<decorator-gen-7>", line 2, in initialize
  File "/opt/conda/lib/python3.6/site-packages/traitlets/config/application.py", line 87, in catch_config_error
    return method(app, *args, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/notebook/notebookapp.py", line 1366, in initialize
    self.init_configurables()
  File "/opt/conda/lib/python3.6/site-packages/notebook/notebookapp.py", line 1100, in init_configurables
    connection_dir=self.runtime_dir,
  File "/opt/conda/lib/python3.6/site-packages/traitlets/traitlets.py", line 556, in __get__
    return self.get(obj, cls)
  File "/opt/conda/lib/python3.6/site-packages/traitlets/traitlets.py", line 535, in get
    value = self._validate(obj, dynamic_default())
  File "/opt/conda/lib/python3.6/site-packages/jupyter_core/application.py", line 99, in _runtime_dir_default
    ensure_dir_exists(rd, mode=0o700)
  File "/opt/conda/lib/python3.6/site-packages/jupyter_core/utils/__init__.py", line 13, in ensure_dir_exists
    os.makedirs(path, mode=mode)
  File "/opt/conda/lib/python3.6/os.py", line 210, in makedirs
    makedirs(head, mode, exist_ok)
  File "/opt/conda/lib/python3.6/os.py", line 210, in makedirs
    makedirs(head, mode, exist_ok)
  File "/opt/conda/lib/python3.6/os.py", line 220, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/home/jovyan/.local/share'
</code>```

So what happens there is that I am chmod -R 1777 ~/.local because I thought this might help me with the Permission denied error that you'd see at the end of this output.

I do not understand why this is not working. All I want to do is mount an existing directory into my docker container and be able to write files there.

答:
I got this error while running a Docker container with --user although the Dockerimage for the respective container had no

```<code>USER mynamehere
</code>```

in it. The line USER root is not such a good idea, you need to use another username if you want a dedicated user (doesn't matter which as long as its not root). This user can be mapped to fit your local uid/gui by adding

```<code>--user $(id -u):$(id -g)
</code>```

to your docker run command-line.
After that, new files created in attached volumes should be created with the host user's name.

Note: I suggest to give the user mynamehere sudo rights in the Dockerfile by adding this right before the USER mynamehere line:

```<code>RUN apt-get update && apt-get install sudo && \
    adduser --disabled-password --gecos "" udocker && \
    adduser udocker sudo && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
</code>```

Body:
Following setup:

I am a username on a machine. I am in the docker group such that I can run docker, which is installed on that machine.

I'm desperately trying to run jupyter/datascience-notebook on this machine but the problem is I cannot safe files there because the user does not seem to have access rights to the mounted directory.

It is supposed to work like this:

docker run -it --rm -p 8888:8888 -v ~/workspaces:/home/jovyan/work/ -e NB_UID=$(id -u) -e NB_GID=$(id -g) -e GRANT_SUDO=yes jupyter/datascience-notebook

but it does not because I do not have sudo rights.

$ docker run -it --rm -p 8888:8888 -v ~/workspaces:/home/jovyan/work/ -e NB_UID=$(id -u) -e NB_GID=$(id -g) -e GRANT_SUDO=yes jupyter/datascience-notebook
Container must be run as root to set $NB_UID
Container must be run as root to set $NB_GID
Container must be run as root to grant sudo permissions

I was planning to play around with a Dockerfile so I started to write this:

FROM jupyter/datascience-notebook

# Use user root
USER root

RUN ls -la ~/
RUN chown -R jovyan:users ~/.local
RUN chmod -R 1777 ~/.local
RUN ls -la ~/

And here is the reason why: This little helper script below is supposed to create the image test-image and run it afterwards.

#!/usr/bin/env python
import os
import subprocess
from notebook.auth import passwd

cmd = 'docker run -it --rm -p 8888:8888 ' \
    '-v ~/workspaces:/home/jovyan/work ' \
    '-v ~/datasets:/home/jovyan/data ' \
    '-e NB_UID=$(id -u) -e NB_GID=$(id -g) -e GRANT_SUDO=yes ' \
    'test-image start.sh jupyter lab ' \
    '--NotebookApp.token=\'\' '

print('Running {}'.format(cmd))

subprocess.call('docker build --rm -t test-image .', shell=True)
subprocess.call(cmd, shell=True)

For reasons I do not understand I get the following output:

...
Step 14/16 : RUN ls -la ~/
 ---> Running in ef30926edc1a
total 44
drwsrwsr-x 12 jovyan users 4096 Feb 22 12:59 .
drwxr-xr-x 12 root   root  4096 Feb 22 12:59 ..
-rw-rw-r--  1 jovyan users  220 Aug 31  2015 .bash_logout
-rw-rw-r--  1 jovyan users 3771 Aug 31  2015 .bashrc
drwsrwsr-x  3 jovyan users 4096 Feb 20 11:41 .cache
drwsrwsr-x  3 jovyan users 4096 Feb 20 09:29 .conda
drwsrwsr-x  3 jovyan users 4096 Feb 20 11:41 .config
drwxrwsrwt 11 jovyan users 4096 Feb 22 12:59 .local
-rw-rw-r--  1 jovyan users  655 May 16  2017 .profile
drwsrwsr-x  2 jovyan users 4096 Feb 20 09:28 work
drwsrwsr-x  3 jovyan users 4096 Feb 20 09:38 .yarn
 ---> 2de66bf593f3
Removing intermediate container ef30926edc1a
Step 15/16 : RUN ls -la ~/.local/share
...
Set username to: jovyan
usermod: no changes
Set jovyan UID to: 1006
Set jovyan GID to: 1006
Granting jovyan sudo access and appending /opt/conda/bin to sudo PATH
Executing the command: jupyter lab --NotebookApp.token=
Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/site-packages/traitlets/traitlets.py", line 528, in get
    value = obj._trait_values[self.name]
KeyError: 'runtime_dir'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/conda/bin/jupyter-lab", line 6, in <module>
    sys.exit(jupyterlab.labapp.main())
  File "/opt/conda/lib/python3.6/site-packages/jupyter_core/application.py", line 266, in launch_instance
    return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/traitlets/config/application.py", line 657, in launch_instance
    app.initialize(argv)
  File "<decorator-gen-7>", line 2, in initialize
  File "/opt/conda/lib/python3.6/site-packages/traitlets/config/application.py", line 87, in catch_config_error
    return method(app, *args, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/notebook/notebookapp.py", line 1366, in initialize
    self.init_configurables()
  File "/opt/conda/lib/python3.6/site-packages/notebook/notebookapp.py", line 1100, in init_configurables
    connection_dir=self.runtime_dir,
  File "/opt/conda/lib/python3.6/site-packages/traitlets/traitlets.py", line 556, in __get__
    return self.get(obj, cls)
  File "/opt/conda/lib/python3.6/site-packages/traitlets/traitlets.py", line 535, in get
    value = self._validate(obj, dynamic_default())
  File "/opt/conda/lib/python3.6/site-packages/jupyter_core/application.py", line 99, in _runtime_dir_default
    ensure_dir_exists(rd, mode=0o700)
  File "/opt/conda/lib/python3.6/site-packages/jupyter_core/utils/__init__.py", line 13, in ensure_dir_exists
    os.makedirs(path, mode=mode)
  File "/opt/conda/lib/python3.6/os.py", line 210, in makedirs
    makedirs(head, mode, exist_ok)
  File "/opt/conda/lib/python3.6/os.py", line 210, in makedirs
    makedirs(head, mode, exist_ok)
  File "/opt/conda/lib/python3.6/os.py", line 220, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/home/jovyan/.local/share'

So what happens there is that I am chmod -R 1777 ~/.local because I thought this might help me with the Permission denied error that you'd see at the end of this output.

I do not understand why this is not working. All I want to do is mount an existing directory into my docker container and be able to write files there.

Body:
I got this error while running a Docker container with --user although the Dockerimage for the respective container had no

USER mynamehere

in it. The line USER root is not such a good idea, you need to use another username if you want a dedicated user (doesn't matter which as long as its not root). This user can be mapped to fit your local uid/gui by adding

--user $(id -u):$(id -g)

to your docker run command-line.
After that, new files created in attached volumes should be created with the host user's name.

Note: I suggest to give the user mynamehere sudo rights in the Dockerfile by adding this right before the USER mynamehere line:

RUN apt-get update && apt-get install sudo && \
    adduser --disabled-password --gecos "" udocker && \
    adduser udocker sudo && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers


来源: stackexchange

问:
Packing Polygons and Jbutton into Tile
I am making Mahjong game in swing for course project and i am trying to create a Tile, which is actually a simple JButton with some Polygons connected to it. It looks like that (https://imgur.com/af7zzTn).

I created a method, that creates the structure like above, but i have 2 problems:

I dont know how to "pack" structure above into "tile". Lets say, "tile" will be the object of "Tile" class that extends JButton, or JComponent, i'm not sure which one suits it better.

I want to add tiles like above to JLayeredPane, which will allow me, to use 3rd coordinate, like "z", or in other words, to put tiles on top of each other without bugging them, but i also dont know how to do it.

Could you please help me? I am so confused, I spent like 10 hours already fixing a problem like that, but i couldn't find the best solution on the internet. Also i would be happy, if you will make the answer as simply as possible.

Thank you in advance and here is my code:

```<code>public class TestWindow extends JFrame {
static JLayeredPane levels;

public TestWindow() {
    super("Test");
    PanelTest panel = new PanelTest();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(1000, 700);
    setVisible(true);
    add(panel);
    levels = getLayeredPane();
    System.out.println(levels.getSize());
}

//Method for creating Tile, like one on the image
public static void createTestTile(int x, int y, int z, Graphics g) {
    Graphics2D g2d = (Graphics2D) g;

    //Left
    Polygon ml = new Polygon();
    ml.addPoint(x, y);
    ml.addPoint(x - 5, y + 10);
    ml.addPoint(x - 5, y + 70);
    ml.addPoint(x, y + 60);
    g2d.setPaint(Color.LIGHT_GRAY);
    g2d.fillPolygon(ml);
    g2d.setPaint(Color.GRAY);
    g2d.drawLine(x, y + 60, x - 5, y + 69);

    //Middle-bottom
    Polygon mb = new Polygon();
    mb.addPoint(x, y + 60);
    mb.addPoint(x - 5, y + 70);
    mb.addPoint(x + 41, y + 70);
    mb.addPoint(x + 46, y + 60);
    g2d.setPaint(Color.LIGHT_GRAY);
    g2d.fillPolygon(mb);

    //JButton on top
    JButton top = new JButton();
    top.setBounds(x, y, 46, 60);
    TestWindow.levels.add(top, new Integer(z));
}

class PanelTest extends JPanel {

    int x;
    int y;

    public PanelTest() {
        setLayout(null);

    }

    public void paintComponent(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        createTestTile(200, 100, 1, g);
        createTestTile(200, 160, 1, g);
        createTestTile(246, 160, 1, g);
        createTestTile(223, 130, 2, g);
        createTestTile(246, 100, 1, g);
        createTestTile(400, 100, 1, g);
    }

}

public static void main(String[] args) {
    TestWindow window = new TestWindow();
}
</code>```

}

答:
Painting code is for painting only. It should NEVER create a component.

For a game you have two design approaches:

Use real components and customize the components by using features like Borders.

do custom painting for everything.

Your code is trying to mix both approaches, which is incorrect.

i am trying to create a Tile, which is actually a simple JButton with some Polygons connected to it.

If you want to implement the game using real components then you should implement the look you want by using a custom Border to give the button the 3D effect.

Read the section from the Swing tutorial on How to Use Borders

Below is an example that I modified based on the "raised" BevelBorderto paint highlights only on two sides:

```<code>import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * A class which implements a simple tile border.
 */
public class TileBorder extends AbstractBorder
{
    protected int thickness;
    protected Color shadowInner;
    protected Color shadowOuter;

    /**
     * Creates a tile border with the specified type and whose
     * colors will be derived from the background color of the
     * component passed into the paintBorder method.
     * @param thickness the type of tile for the border
     */
    public TileBorder(int thickness) {
        this.thickness = thickness;
    }

    /**
     * Creates a tile border with the specified type, highlight and
     * shadow colors.
     * @param thickness the type of tile for the border
     * @param shadow the color to use for the tile shadow
     */
    public TileBorder(int thickness, Color shadow)
    {
        this(thickness, shadow, shadow.brighter());
    }

    /**
     * Creates a tile border with the specified type, highlight and
     * shadow colors.
     *
     * @param thickness the type of tile for the border
     * @param shadowOuterColor the color to use for the tile outer shadow
     * @param shadowInnerColor the color to use for the tile inner shadow
     */
    public TileBorder(int thickness, Color shadowOuterColor, Color shadowInnerColor)
    {
        this(thickness);
        this.shadowOuter = shadowOuterColor;
        this.shadowInner = shadowInnerColor;
    }

    /**
     * Paints the border for the specified component with the specified
     * position and size.
     * @param c the component for which this border is being painted
     * @param g the paint graphics
     * @param x the x position of the painted border
     * @param y the y position of the painted border
     * @param width the width of the painted border
     * @param height the height of the painted border
     */
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
    {
        int h = height;
        int w = width;
        int t = thickness;
        int m = thickness / 2;

        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.translate(x, y);

        //  Paint border on right/bottom of component

        Shape outer = new Rectangle(0, 0, w - 1, h - 1);
        Shape inner = new Rectangle(0, 0, w - t, h - t);

        Area border = new Area( outer );
        border.subtract( new Area(inner) );

        g2d.setColor(getShadowInnerColor(c));
        g2d.fill( border );

        // Highlight border edge

        g2d.setColor(getShadowOuterColor(c));

        g2d.draw( border );
        g2d.drawLine(0, 0, w - t, 0);
        g2d.drawLine(0, 0, 0, h - t);
        g2d.drawLine(w - t, h - t, w, h);

        //  Fill border edge with background color of parent component

        g2d.setColor( c.getParent().getBackground() );

        Polygon topRight = new Polygon();
        topRight.addPoint(w - t, 0);
        topRight.addPoint(w, 0);
        topRight.addPoint(w, m);
        g2d.fillPolygon(topRight);

        Polygon bottomLeft = new Polygon();
        bottomLeft.addPoint(0, h - t);
        bottomLeft.addPoint(0, h);
        bottomLeft.addPoint(m, h);
        g2d.fillPolygon(bottomLeft);

        //  Cleanup

        g2d.dispose();
    }

    /**
     * Reinitialize the insets parameter with this Border's current Insets.
     * @param c the component for which this border insets value applies
     * @param insets the object to be reinitialized
     */
    public Insets getBorderInsets(Component c, Insets insets)
    {
        insets.set(0, 0, thickness, thickness);
        return insets;
    }

    /**
     * Returns the inner shadow color of the tile border
     * when rendered on the specified component.  If no shadow
     * color was specified at instantiation, the shadow color
     * is derived from the specified component's background color.
     * @param c the component for which the shadow may be derived
     */
    public Color getShadowInnerColor(Component c)
    {
        Color shadow = getShadowInnerColor();
        return shadow != null ? shadow : c.getBackground().darker();
    }

    /**
     * Returns the outer shadow color of the tile border
     * when rendered on the specified component.  If no shadow
     * color was specified at instantiation, the shadow color
     * is derived from the specified component's background color.
     * @param c the component for which the shadow may be derived
     */
    public Color getShadowOuterColor(Component c)
    {
        Color shadow = getShadowOuterColor();
        return shadow != null ? shadow : c.getBackground().darker().darker();
    }

    /**
     * Returns the inner shadow color of the tile border.
     * Will return null if no shadow color was specified
     * at instantiation.
     */
    public Color getShadowInnerColor()
    {
        return shadowInner;
    }

    /**
     * Returns the outer shadow color of the tile border.
     * Will return null if no shadow color was specified
     * at instantiation.
     */
    public Color getShadowOuterColor()
    {
        return shadowOuter;
    }

    /**
     * Returns whether or not the border is opaque.
     */
    public boolean isBorderOpaque()
    {
        return true;
    }

    private static void createAndShowGUI()
    {
        Border tile = new TileBorder(6);
        JPanel panel = new JPanel( new FlowLayout(FlowLayout.LEFT, 0, 0) );

        for (int i = 0; i < 5; i++)
        {
            JButton button = new JButton();
            button.setPreferredSize( new Dimension(50, 100) );
            button.setBorder( tile );
            panel.add( button );
        }

        JLayeredPane layeredPane = new JLayeredPane();
        int locationX = 20;
        int locationY = 50;

        for (int i = 0; i < 5; i++)
        {
            JButton button = new JButton();
            button.setSize( new Dimension(50, 100) );
            button.setLocation(locationX, locationY);
            button.setBorder( tile );
            panel.add( button );
            layeredPane.add(button, new Integer(i));
            locationX += 6;
            locationY -= 6;
        }

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel, BorderLayout.PAGE_START);
        frame.add(layeredPane, BorderLayout.CENTER);
        frame.setSize(300, 300);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
    }
}
</code>```

It allows you to customize the thickness of the Border as well as specify border colors.

You can also check out How to Use Layered Panes for working examples.

ContentLicense: CC BY-SA 4.0

Title: Packing Polygons and Jbutton into Tile

Body:
I am making Mahjong game in swing for course project and i am trying to create a Tile, which is actually a simple JButton with some Polygons connected to it. It looks like that (https://imgur.com/af7zzTn).

I created a method, that creates the structure like above, but i have 2 problems:

I dont know how to "pack" structure above into "tile". Lets say, "tile" will be the object of "Tile" class that extends JButton, or JComponent, i'm not sure which one suits it better.

I want to add tiles like above to JLayeredPane, which will allow me, to use 3rd coordinate, like "z", or in other words, to put tiles on top of each other without bugging them, but i also dont know how to do it.

Could you please help me? I am so confused, I spent like 10 hours already fixing a problem like that, but i couldn't find the best solution on the internet. Also i would be happy, if you will make the answer as simply as possible.

Thank you in advance and here is my code:

public class TestWindow extends JFrame {
static JLayeredPane levels;

public TestWindow() {
    super("Test");
    PanelTest panel = new PanelTest();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(1000, 700);
    setVisible(true);
    add(panel);
    levels = getLayeredPane();
    System.out.println(levels.getSize());
}

//Method for creating Tile, like one on the image
public static void createTestTile(int x, int y, int z, Graphics g) {
    Graphics2D g2d = (Graphics2D) g;

    //Left
    Polygon ml = new Polygon();
    ml.addPoint(x, y);
    ml.addPoint(x - 5, y + 10);
    ml.addPoint(x - 5, y + 70);
    ml.addPoint(x, y + 60);
    g2d.setPaint(Color.LIGHT_GRAY);
    g2d.fillPolygon(ml);
    g2d.setPaint(Color.GRAY);
    g2d.drawLine(x, y + 60, x - 5, y + 69);

    //Middle-bottom
    Polygon mb = new Polygon();
    mb.addPoint(x, y + 60);
    mb.addPoint(x - 5, y + 70);
    mb.addPoint(x + 41, y + 70);
    mb.addPoint(x + 46, y + 60);
    g2d.setPaint(Color.LIGHT_GRAY);
    g2d.fillPolygon(mb);

    //JButton on top
    JButton top = new JButton();
    top.setBounds(x, y, 46, 60);
    TestWindow.levels.add(top, new Integer(z));
}

class PanelTest extends JPanel {

    int x;
    int y;

    public PanelTest() {
        setLayout(null);

    }

    public void paintComponent(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        createTestTile(200, 100, 1, g);
        createTestTile(200, 160, 1, g);
        createTestTile(246, 160, 1, g);
        createTestTile(223, 130, 2, g);
        createTestTile(246, 100, 1, g);
        createTestTile(400, 100, 1, g);
    }

}

public static void main(String[] args) {
    TestWindow window = new TestWindow();
}

}

Body:
Painting code is for painting only. It should NEVER create a component.

For a game you have two design approaches:

Use real components and customize the components by using features like Borders.

do custom painting for everything.

Your code is trying to mix both approaches, which is incorrect.

i am trying to create a Tile, which is actually a simple JButton with some Polygons connected to it.

If you want to implement the game using real components then you should implement the look you want by using a custom Border to give the button the 3D effect.

Read the section from the Swing tutorial on How to Use Borders

Below is an example that I modified based on the "raised" BevelBorderto paint highlights only on two sides:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * A class which implements a simple tile border.
 */
public class TileBorder extends AbstractBorder
{
    protected int thickness;
    protected Color shadowInner;
    protected Color shadowOuter;

    /**
     * Creates a tile border with the specified type and whose
     * colors will be derived from the background color of the
     * component passed into the paintBorder method.
     * @param thickness the type of tile for the border
     */
    public TileBorder(int thickness) {
        this.thickness = thickness;
    }

    /**
     * Creates a tile border with the specified type, highlight and
     * shadow colors.
     * @param thickness the type of tile for the border
     * @param shadow the color to use for the tile shadow
     */
    public TileBorder(int thickness, Color shadow)
    {
        this(thickness, shadow, shadow.brighter());
    }

    /**
     * Creates a tile border with the specified type, highlight and
     * shadow colors.
     *
     * @param thickness the type of tile for the border
     * @param shadowOuterColor the color to use for the tile outer shadow
     * @param shadowInnerColor the color to use for the tile inner shadow
     */
    public TileBorder(int thickness, Color shadowOuterColor, Color shadowInnerColor)
    {
        this(thickness);
        this.shadowOuter = shadowOuterColor;
        this.shadowInner = shadowInnerColor;
    }

    /**
     * Paints the border for the specified component with the specified
     * position and size.
     * @param c the component for which this border is being painted
     * @param g the paint graphics
     * @param x the x position of the painted border
     * @param y the y position of the painted border
     * @param width the width of the painted border
     * @param height the height of the painted border
     */
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
    {
        int h = height;
        int w = width;
        int t = thickness;
        int m = thickness / 2;

        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.translate(x, y);

        //  Paint border on right/bottom of component

        Shape outer = new Rectangle(0, 0, w - 1, h - 1);
        Shape inner = new Rectangle(0, 0, w - t, h - t);

        Area border = new Area( outer );
        border.subtract( new Area(inner) );

        g2d.setColor(getShadowInnerColor(c));
        g2d.fill( border );

        // Highlight border edge

        g2d.setColor(getShadowOuterColor(c));

        g2d.draw( border );
        g2d.drawLine(0, 0, w - t, 0);
        g2d.drawLine(0, 0, 0, h - t);
        g2d.drawLine(w - t, h - t, w, h);

        //  Fill border edge with background color of parent component

        g2d.setColor( c.getParent().getBackground() );

        Polygon topRight = new Polygon();
        topRight.addPoint(w - t, 0);
        topRight.addPoint(w, 0);
        topRight.addPoint(w, m);
        g2d.fillPolygon(topRight);

        Polygon bottomLeft = new Polygon();
        bottomLeft.addPoint(0, h - t);
        bottomLeft.addPoint(0, h);
        bottomLeft.addPoint(m, h);
        g2d.fillPolygon(bottomLeft);

        //  Cleanup

        g2d.dispose();
    }

    /**
     * Reinitialize the insets parameter with this Border's current Insets.
     * @param c the component for which this border insets value applies
     * @param insets the object to be reinitialized
     */
    public Insets getBorderInsets(Component c, Insets insets)
    {
        insets.set(0, 0, thickness, thickness);
        return insets;
    }

    /**
     * Returns the inner shadow color of the tile border
     * when rendered on the specified component.  If no shadow
     * color was specified at instantiation, the shadow color
     * is derived from the specified component's background color.
     * @param c the component for which the shadow may be derived
     */
    public Color getShadowInnerColor(Component c)
    {
        Color shadow = getShadowInnerColor();
        return shadow != null ? shadow : c.getBackground().darker();
    }

    /**
     * Returns the outer shadow color of the tile border
     * when rendered on the specified component.  If no shadow
     * color was specified at instantiation, the shadow color
     * is derived from the specified component's background color.
     * @param c the component for which the shadow may be derived
     */
    public Color getShadowOuterColor(Component c)
    {
        Color shadow = getShadowOuterColor();
        return shadow != null ? shadow : c.getBackground().darker().darker();
    }

    /**
     * Returns the inner shadow color of the tile border.
     * Will return null if no shadow color was specified
     * at instantiation.
     */
    public Color getShadowInnerColor()
    {
        return shadowInner;
    }

    /**
     * Returns the outer shadow color of the tile border.
     * Will return null if no shadow color was specified
     * at instantiation.
     */
    public Color getShadowOuterColor()
    {
        return shadowOuter;
    }

    /**
     * Returns whether or not the border is opaque.
     */
    public boolean isBorderOpaque()
    {
        return true;
    }

    private static void createAndShowGUI()
    {
        Border tile = new TileBorder(6);
        JPanel panel = new JPanel( new FlowLayout(FlowLayout.LEFT, 0, 0) );

        for (int i = 0; i < 5; i++)
        {
            JButton button = new JButton();
            button.setPreferredSize( new Dimension(50, 100) );
            button.setBorder( tile );
            panel.add( button );
        }

        JLayeredPane layeredPane = new JLayeredPane();
        int locationX = 20;
        int locationY = 50;

        for (int i = 0; i < 5; i++)
        {
            JButton button = new JButton();
            button.setSize( new Dimension(50, 100) );
            button.setLocation(locationX, locationY);
            button.setBorder( tile );
            panel.add( button );
            layeredPane.add(button, new Integer(i));
            locationX += 6;
            locationY -= 6;
        }

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel, BorderLayout.PAGE_START);
        frame.add(layeredPane, BorderLayout.CENTER);
        frame.setSize(300, 300);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
    }
}

It allows you to customize the thickness of the Border as well as specify border colors.

You can also check out How to Use Layered Panes for working examples.


问:
AntDesign TabPane min-height 100%
Using Ant.Design Tabs https://ant.design/components/tabs/

How can I set styling on TabPane so that it's min-height is always 100% height of the window even when it's empty?

Below example should cover the window with color #F5F5F5

答:
So this has worked for me too</p>

```<code>   <Tabs
      onChange={() => {
      console.log("oi");
      }}
      type="card"
      style={{ background: "blue", height: "100%" }}
   >
   <TabPane
      tab="Tab 1"
      key="1"
      style={{ minHeight: "100vh", background: "red" }}
   >
      Content of Tab Pane 1
   </TabPane>
 </Tabs>
</code>```

Title: AntDesign TabPane min-height 100%

Body:
So this has worked for me too

   <Tabs
      onChange={() => {
      console.log("oi");
      }}
      type="card"
      style={{ background: "blue", height: "100%" }}
   >
   <TabPane
      tab="Tab 1"
      key="1"
      style={{ minHeight: "100vh", background: "red" }}
   >
      Content of Tab Pane 1
   </TabPane>
 </Tabs>


问:
Parse string as datetime.timedelta argument
Consider this method :

```<code>def duration(duration_type, t):
    t = timedelta(duration_type=t)
</code>```

where duration_type is a string representing one of timedelta arguments (days,hours,seconds,etc.)

Is there a way to correctly parse the string and feed it as an argument ? Similar to setattr() when working with attributes.

Obviously, the code above generates the following error:

TypeError: 'duration_type' is an invalid keyword argument for __new__()

Use case : Read this value from default python config file and use it in a timedelta object.

答:
You could use special ** (double asterisk) to pass dict as named arguments in a function:

def duration(duration_type, t):
    kwargs = {duration_type: t}
    return timedelta(**kwargs)
```

Body:
Consider this method :

def duration(duration_type, t):
    t = timedelta(duration_type=t)

where duration_type is a string representing one of timedelta arguments (days,hours,seconds,etc.)

Is there a way to correctly parse the string and feed it as an argument ? Similar to setattr() when working with attributes.

Obviously, the code above generates the following error:

TypeError: 'duration_type' is an invalid keyword argument for __new__()

Use case : Read this value from default python config file and use it in a timedelta object.


问:
How to replace a title in span with plain text and username (or diplay name) with PHP
Here is my situation.

I'm using flatsome theme with woocommerce. In its theme customizer, I can just check option boxes to make Account header show "Login / Register" before logging in and show display name (TEST in picture) after logging in. https://imgur.com/7tekdTo https://imgur.com/dYWQg75

These options work correctly on desktop but on mobile website it is not at all. These options don't apply. I figure my only choice here is JavaScript. But I know next to nothing about HTML and JavaScript. https://imgur.com/p6Tn7Ig https://imgur.com/0i1tCkB

My question here are

How can I change Login to Login / Register before logging in on mobile.

How can I make it show display name instead of My Account after logging in on mobile.

I really want to save cost so plug-in isn't viable option for me. I prefer this default header too because creating custom menu I can't use popup login / register screen. I have searched online and none of solution work so far.

These are my elements of the mentioned account header.

Before logging in.

```<code><a href="https://www.mywebsite.com/my-account/" class="nav-top-link nav-top-not-logged-in " data-open="#login-form-popup">
<span>
Login / Register </span>
</a>
</code>```

After logging in.

```<code><a href="https://www.mywebsite.com/my-account/" class="account-link account-login
  " title="My account">

            <span class="header-account-title">
        test        </span>
</a>
</code>```

答:
For now, I found a temporary solution to my first question. I use additional CSS to replace the text.

```<code>.nav-top-link.nav-top-not-logged-in  span {
  display: none;
}
.nav-top-link.nav-top-not-logged-in:after {
  content: 'Login / Register';
}
</code>```

Where nav-top-link nav-top-not-logged-in is the class of the header before logging in.

Also, I did some digging and I found the files. There are 2 files for this. It appears that the theme use 2 different codes for desktop and mobile. (/wp-content/themes/flatsome/template-parts/header/partials)

There is 1 file called element-account.php.

```<code><?php $icon_style = get_theme_mod('account_icon_style'); ?>
<?php if(is_woocommerce_activated()){ ?>
<li class="account-item has-icon
  <?php if(is_account_page()) echo ' active'; ?>
  <?php if ( is_user_logged_in() ) { ?> has-dropdown<?php } ?>"
>
<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '<div class="header-button">'; ?>

<?php if ( is_user_logged_in() ) { ?>
<a href="<?php echo get_permalink( get_option('woocommerce_myaccount_page_id') ); ?>" class="account-link account-login
  <?php if($icon_style && $icon_style !== 'image') echo get_flatsome_icon_class($icon_style, 'small'); ?>"
  title="<?php _e('My account', 'woocommerce'); ?>">

    <?php if ( get_theme_mod( 'header_account_title', 1 ) ) { ?>
        <span class="header-account-title">
        <?php
        if ( get_theme_mod( 'header_account_username' ) ) {
            $current_user = wp_get_current_user();
            echo esc_html( $current_user->display_name );
        } else {
            esc_html_e( 'My account', 'woocommerce' );
        }
        ?>
        </span>
    <?php } ?>

  <?php if($icon_style == 'image'){
    echo '<i class="image-icon circle">'.get_avatar(get_current_user_id()).'</i>';
   } else  if($icon_style){
    echo get_flatsome_icon('icon-user');
   } ?>

</a><!-- .account-link -->

<?php } else { ?>
<a href="<?php echo get_permalink( get_option('woocommerce_myaccount_page_id') ); ?>"
    class="nav-top-link nav-top-not-logged-in <?php if($icon_style && $icon_style !== 'image') echo get_flatsome_icon_class($icon_style, 'small'); ?>"
    <?php if( get_theme_mod('account_login_style','lightbox') == 'lightbox' && !is_checkout() && !is_account_page() ) echo 'data-open="#login-form-popup"'; ?>
  >
  <?php if(get_theme_mod('header_account_title', 1)) { ?>
  <span>
    <?php _e('Login', 'woocommerce'); ?>
    <?php if(get_theme_mod('header_account_register')){
        echo ' / '.__('Register', 'woocommerce');
      } ?>
  </span>
  <?php } else {
        echo get_flatsome_icon('icon-user');
    } ?>

</a><!-- .account-login-link -->
<?php } ?>

<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '</div>'; ?>

<?php
// Show Dropdown for logged in users
if ( is_user_logged_in() ) { ?>
<ul class="nav-dropdown  <?php flatsome_dropdown_classes(); ?>">
    <?php wc_get_template('myaccount/account-links.php'); ?>
</ul>
<?php } ?>

</li>
<?php } else {
    fl_header_element_error( 'woocommerce' );
}
?>
</code>```

And there is another file called element-account-mobile.php

```<code><?php $icon_style = flatsome_option('account_icon_style'); ?>
<li class="account-item has-icon">
<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '<div class="header-button">'; ?>
    <a href="<?php echo get_permalink( get_option('woocommerce_myaccount_page_id') ); ?>"
    class="account-link-mobile <?php echo get_flatsome_icon_class($icon_style, 'small');?>" title="<?php _e('My account', 'woocommerce'); ?>">
      <?php echo get_flatsome_icon('icon-user'); ?>
    </a><!-- .account-link -->
<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '</div>'; ?>
</li>
</code>```

Body:
Here is my situation.

I'm using flatsome theme with woocommerce. In its theme customizer, I can just check option boxes to make Account header show "Login / Register" before logging in and show display name (TEST in picture) after logging in. https://imgur.com/7tekdTo https://imgur.com/dYWQg75

These options work correctly on desktop but on mobile website it is not at all. These options don't apply. I figure my only choice here is JavaScript. But I know next to nothing about HTML and JavaScript. https://imgur.com/p6Tn7Ig https://imgur.com/0i1tCkB

My question here are

How can I change Login to Login / Register before logging in on mobile.

How can I make it show display name instead of My Account after logging in on mobile.

I really want to save cost so plug-in isn't viable option for me. I prefer this default header too because creating custom menu I can't use popup login / register screen. I have searched online and none of solution work so far.

These are my elements of the mentioned account header.

Before logging in.

Login / Register

After logging in.

        test

Body:
For now, I found a temporary solution to my first question. I use additional CSS to replace the text.

.nav-top-link.nav-top-not-logged-in  span {
  display: none;
}
.nav-top-link.nav-top-not-logged-in:after {
  content: 'Login / Register';
}

Where nav-top-link nav-top-not-logged-in is the class of the header before logging in.

Also, I did some digging and I found the files. There are 2 files for this. It appears that the theme use 2 different codes for desktop and mobile. (/wp-content/themes/flatsome/template-parts/header/partials)

There is 1 file called element-account.php.

<?php $icon_style = get_theme_mod('account_icon_style'); ?>
<?php if(is_woocommerce_activated()){ ?>
<li class="account-item has-icon
  <?php if(is_account_page()) echo ' active'; ?>
  <?php if ( is_user_logged_in() ) { ?> has-dropdown<?php } ?>"
>
<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '<div class="header-button">'; ?>

<?php if ( is_user_logged_in() ) { ?>
<a href="<?php echo get_permalink( get_option('woocommerce_myaccount_page_id') ); ?>" class="account-link account-login
  <?php if($icon_style && $icon_style !== 'image') echo get_flatsome_icon_class($icon_style, 'small'); ?>"
  title="<?php _e('My account', 'woocommerce'); ?>">

    <?php if ( get_theme_mod( 'header_account_title', 1 ) ) { ?>
        <span class="header-account-title">
        <?php
        if ( get_theme_mod( 'header_account_username' ) ) {
            $current_user = wp_get_current_user();
            echo esc_html( $current_user->display_name );
        } else {
            esc_html_e( 'My account', 'woocommerce' );
        }
        ?>
        </span>
    <?php } ?>

  <?php if($icon_style == 'image'){
    echo '<i class="image-icon circle">'.get_avatar(get_current_user_id()).'</i>';
   } else  if($icon_style){
    echo get_flatsome_icon('icon-user');
   } ?>

</a><!-- .account-link -->

<?php } else { ?>
<a href="<?php echo get_permalink( get_option('woocommerce_myaccount_page_id') ); ?>"
    class="nav-top-link nav-top-not-logged-in <?php if($icon_style && $icon_style !== 'image') echo get_flatsome_icon_class($icon_style, 'small'); ?>"
    <?php if( get_theme_mod('account_login_style','lightbox') == 'lightbox' && !is_checkout() && !is_account_page() ) echo 'data-open="#login-form-popup"'; ?>
  >
  <?php if(get_theme_mod('header_account_title', 1)) { ?>
  <span>
    <?php _e('Login', 'woocommerce'); ?>
    <?php if(get_theme_mod('header_account_register')){
        echo ' / '.__('Register', 'woocommerce');
      } ?>
  </span>
  <?php } else {
        echo get_flatsome_icon('icon-user');
    } ?>

</a><!-- .account-login-link -->
<?php } ?>

<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '</div>'; ?>

<?php
// Show Dropdown for logged in users
if ( is_user_logged_in() ) { ?>
<ul class="nav-dropdown  <?php flatsome_dropdown_classes(); ?>">
    <?php wc_get_template('myaccount/account-links.php'); ?>
</ul>
<?php } ?>

</li>
<?php } else {
    fl_header_element_error( 'woocommerce' );
}
?>

And there is another file called element-account-mobile.php

<?php $icon_style = flatsome_option('account_icon_style'); ?>
<li class="account-item has-icon">
<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '<div class="header-button">'; ?>
    <a href="<?php echo get_permalink( get_option('woocommerce_myaccount_page_id') ); ?>"
    class="account-link-mobile <?php echo get_flatsome_icon_class($icon_style, 'small');?>" title="<?php _e('My account', 'woocommerce'); ?>">
      <?php echo get_flatsome_icon('icon-user'); ?>
    </a><!-- .account-link -->
<?php if($icon_style && $icon_style !== 'image' && $icon_style !== 'plain') echo '</div>'; ?>
</li>


问:
.doc to pdf using python
I'am tasked with converting tons of .doc files to .pdf. And the only way my supervisor wants me to do this is through MSWord 2010. I know I should be able to automate this with python COM automation. Only problem is I dont know how and where to start. I tried searching for some tutorials but was not able to find any (May be I might have, but I don't know what I'm looking for).

Right now I'm reading through this. Dont know how useful this is going to be.

答:
I was working with this solution but I needed to search all .docx, .dotm, .docm, .odt, .doc or .rtf and then turn them all to .pdf (python 3.7.5). Hope it works...

```<code>import os
import win32com.client

wdFormatPDF = 17

for root, dirs, files in os.walk(r'your directory here'):
    for f in files:

        if  f.endswith(".doc")  or f.endswith(".odt") or f.endswith(".rtf"):
            try:
                print(f)
                in_file=os.path.join(root,f)
                word = win32com.client.Dispatch('Word.Application')
                word.Visible = False
                doc = word.Documents.Open(in_file)
                doc.SaveAs(os.path.join(root,f[:-4]), FileFormat=wdFormatPDF)
                doc.Close()
                word.Quit()
                word.Visible = True
                print ('done')
                os.remove(os.path.join(root,f))
                pass
            except:
                print('could not open')
                # os.remove(os.path.join(root,f))
        elif f.endswith(".docx") or f.endswith(".dotm") or f.endswith(".docm"):
            try:
                print(f)
                in_file=os.path.join(root,f)
                word = win32com.client.Dispatch('Word.Application')
                word.Visible = False
                doc = word.Documents.Open(in_file)
                doc.SaveAs(os.path.join(root,f[:-5]), FileFormat=wdFormatPDF)
                doc.Close()
                word.Quit()
                word.Visible = True
                print ('done')
                os.remove(os.path.join(root,f))
                pass
            except:
                print('could not open')
                # os.remove(os.path.join(root,f))
        else:
            pass
</code>```

The try and except was for those documents I couldn't read and won't exit the code until the last document.

ContentLicense: CC BY-SA 3.0

Title: .doc to pdf using python

Body:
I was working with this solution but I needed to search all .docx, .dotm, .docm, .odt, .doc or .rtf and then turn them all to .pdf (python 3.7.5). Hope it works...

import os
import win32com.client

wdFormatPDF = 17

for root, dirs, files in os.walk(r'your directory here'):
    for f in files:

        if  f.endswith(".doc")  or f.endswith(".odt") or f.endswith(".rtf"):
            try:
                print(f)
                in_file=os.path.join(root,f)
                word = win32com.client.Dispatch('Word.Application')
                word.Visible = False
                doc = word.Documents.Open(in_file)
                doc.SaveAs(os.path.join(root,f[:-4]), FileFormat=wdFormatPDF)
                doc.Close()
                word.Quit()
                word.Visible = True
                print ('done')
                os.remove(os.path.join(root,f))
                pass
            except:
                print('could not open')
                # os.remove(os.path.join(root,f))
        elif f.endswith(".docx") or f.endswith(".dotm") or f.endswith(".docm"):
            try:
                print(f)
                in_file=os.path.join(root,f)
                word = win32com.client.Dispatch('Word.Application')
                word.Visible = False
                doc = word.Documents.Open(in_file)
                doc.SaveAs(os.path.join(root,f[:-5]), FileFormat=wdFormatPDF)
                doc.Close()
                word.Quit()
                word.Visible = True
                print ('done')
                os.remove(os.path.join(root,f))
                pass
            except:
                print('could not open')
                # os.remove(os.path.join(root,f))
        else:
            pass

The try and except was for those documents I couldn't read and won't exit the code until the last document.


问:
How does it know the address of the DB without passing it to the Schemas?
It is not usual to ask a question when something is working, but this is working to well.
I am using a connection with a Mongodb in a Nuxt application.

The only place the address of the DB is declared is in the index.js

```<code>const express = require('express');
const mongoose = require('mongoose');

const apiRouter = require('./apiRouter');

const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost/sun-v2', {useNewUrlParser: true})

app.use(apiRouter);

module.exports = {
   path: '/server',
   handler: app
}
</code>```

As you can see the mongoose Object is not exported.
In my apiRouter.js the Models are required and works perfectly:

```<code>const express = require('express');
const PlayerModel = require('./models/player');
const app = express();

app.get('/players', async (req, res) => {
    const players = await PlayerModel.find({});

    try {
        res.send(players);
    } catch (error) {
        res.status(500).send(error);
    }
});
</code>```

What I don't understand is how the Model.find() knows where to search for the DB, if neither the path nor the connection is exported.

What if I had more than one DB address, how could I choose the connection I want to use?
I have more than one open mongo database, how does it know it has to use the one I made connection to in index?

答:
When you use mongoose.connect(), mongoose is creating a connection internally and making it the "default connection". This is a convenience that works for most of the cases.

If you need more than one connection then you have to create them manually by using the method mongoose.createConnection() (which is the method used by mongoose.connect() under the hood).

const conn = mongoose.createConnection("mongodb://localhost/sun-v2", {
  useNewUrlParser: true
});
```

<p>There is one caveat though, you cannot simply export you <strong>models</strong> anymore. You will have to export you <strong>schemas</strong> instead, so you can create separate models for each connection. In your case you will have something like this:</p>

```const express = require('express');
const mongoose = require('mongoose');

// Export your schema instead your model
const PlayerSchema = require('./models/player');
const app = express();

const conn1 = mongoose.createConnection("mongodb://localhost/sun-v2", {
  useNewUrlParser: true
});
const conn2 = mongoose.createConnection("mongodb://anotherhost/sun-v2", {
  useNewUrlParser: true
});

// ...

const PlayerModel1 = conn1.model('User', PlayerSchema);
const PlayerModel2 = conn2.model('User', PlayerSchema);

// ...

app.get('/players', async (req, res) => {
    const playersFromConn1 = await PlayerModel1.find({});
    const playersFromConn2 = await PlayerModel2.find({});

    // ...
});
```

You can check the Mongoose documentation for more information about multiple connections on https://mongoosejs.com/docs/connections.html#multiple_connections

Body:
It is not usual to ask a question when something is working, but this is working to well.
I am using a connection with a Mongodb in a Nuxt application.

The only place the address of the DB is declared is in the index.js

const express = require('express');
const mongoose = require('mongoose');

const apiRouter = require('./apiRouter');

const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost/sun-v2', {useNewUrlParser: true})

app.use(apiRouter);

module.exports = {
   path: '/server',
   handler: app
}

As you can see the mongoose Object is not exported.
In my apiRouter.js the Models are required and works perfectly:

const express = require('express');
const PlayerModel = require('./models/player');
const app = express();

app.get('/players', async (req, res) => {
    const players = await PlayerModel.find({});

    try {
        res.send(players);
    } catch (error) {
        res.status(500).send(error);
    }
});

What I don't understand is how the Model.find() knows where to search for the DB, if neither the path nor the connection is exported.

What if I had more than one DB address, how could I choose the connection I want to use?
I have more than one open mongo database, how does it know it has to use the one I made connection to in index?

Body:
When you use mongoose.connect(), mongoose is creating a connection internally and making it the "default connection". This is a convenience that works for most of the cases.

If you need more than one connection then you have to create them manually by using the method mongoose.createConnection() (which is the method used by mongoose.connect() under the hood).

const conn = mongoose.createConnection("mongodb://localhost/sun-v2", {
  useNewUrlParser: true
});

There is one caveat though, you cannot simply export you models anymore. You will have to export you schemas instead, so you can create separate models for each connection. In your case you will have something like this:

const express = require('express');
const mongoose = require('mongoose');

// Export your schema instead your model
const PlayerSchema = require('./models/player');
const app = express();

const conn1 = mongoose.createConnection("mongodb://localhost/sun-v2", {
  useNewUrlParser: true
});
const conn2 = mongoose.createConnection("mongodb://anotherhost/sun-v2", {
  useNewUrlParser: true
});

// ...

const PlayerModel1 = conn1.model('User', PlayerSchema);
const PlayerModel2 = conn2.model('User', PlayerSchema);

// ...

app.get('/players', async (req, res) => {
    const playersFromConn1 = await PlayerModel1.find({});
    const playersFromConn2 = await PlayerModel2.find({});

    // ...
});

You can check the Mongoose documentation for more information about multiple connections on https://mongoosejs.com/docs/connections.html#multiple_connections


问:
Heroku custom domain ssl name mismatch error
I've added a custom domain (bought on GoDaddy) to my Heroku app and am on the hobby dyno. When I type in www.example.com everything works fine, but when I open example.com I get a name mismatch error.

My cname host www points to example-78914389.herokudns.com and I have forward to https://www.example.com on GoDaddy enabled.

The certificate is only valid for the following names: shortener.secureserver.net, www.shortener.secureserver.net.

Why is the certificate valid for these domains and not for my example.com?
I don't know if it matters, but I just ported the domain from zeit now to GoDaddy.

答:
Problem solved!
I transferred my domain from GoDaddy to namecheap, then made an ALIAS record. I've also added example.com to my app in Heroku. I now have www.example.com and example.com added and both domains work.

If you have the same issue, check this out: https://devcenter.heroku.com/articles/custom-domains#add-a-custom-root-domain


问:
How to specify default Logback configuration for any spring profile that is not already present in the config
Here is my simplified logback-spring.xml configuration:

<configuration>

    <springProfile name=dev>

    </springProfile>

    <springProfile name=prod>

    </springProfile>

</configuration>
```

I would like to get some default logback configuration when I am running my app with some different profile. I couldn't find information about having some default configuration in logback-spring.xml.

Please, note that there are more than 2 profiles defined and I don't know the names of other temp profiles.

Thanks,
Pavlo

答:
You can define it like this:

```<code><configuration>

<!-- appender config -->

<springProfile name=dev>
    <!-- dev specific config here -->
</springProfile>

<springProfile name=prod>
    <!-- prod specific config here -->
</springProfile>

<!-- other profiles -->

<springProfile name="!(dev| prod)">
   <!-- other specific config here -->
</springProfile>
</code>```

Body:
Here is my simplified logback-spring.xml configuration:

<configuration>

    <springProfile name=dev>

    </springProfile>

    <springProfile name=prod>

    </springProfile>

</configuration>

I would like to get some default logback configuration when I am running my app with some different profile. I couldn't find information about having some default configuration in logback-spring.xml.

Please, note that there are more than 2 profiles defined and I don't know the names of other temp profiles.

Thanks,
Pavlo

Body:
You can define it like this:

<configuration>

<!-- appender config -->

<springProfile name=dev>
    <!-- dev specific config here -->
</springProfile>

<springProfile name=prod>
    <!-- prod specific config here -->
</springProfile>

<!-- other profiles -->

<springProfile name="!(dev| prod)">
   <!-- other specific config here -->
</springProfile>


问:
Reversing CGRect - Swift
How can I reverse my origin.x? my origin.x started from right I want start from left. For example these origins of x in my application started from the far right:

1) 351.0

2) 304.0

3) 257.0

4) 210.0

5) 163.0

6) 116.0

7) 69.0

8) 22.0

How can I reverse these origins and started from 22.0 and end to 351.0 ?

Code:

```<code>var ansWithoutSpaces = String()
ansWithoutSpaces = answersString.replacingOccurrences(of: " ", with: "")

var targetHeigt = CGFloat()
let viewWidth = self.view.frame.size.width

if viewWidth == 320 {
    targetHeigt = 2.5
} else {
    targetHeigt = 5
}

let yAxis : Int = Int((self.view.frame.height) * 60%)
let lenghtOfChar = ansWithoutSpaces as NSString
// char count
let width: Int = Int(view.frame.size.width) - 40
// frame width
var targetWidth: Int = (width - (lenghtOfChar.length - 1) * 5) / lenghtOfChar.length

if targetWidth > 50 {
    if viewWidth == 320 {
        targetWidth = 38
    } else if viewWidth == 375 {
        targetWidth = 45
    } else {
        targetWidth = 50
    }
}

let totalWidth: Int = (targetWidth * lenghtOfChar.length) + ((lenghtOfChar.length - 1) * 5)

for x in 0..<ansWithoutSpaces.count {
    let xAxis: Int = (width / 2) - (totalWidth / 2) + (x * targetWidth) + (x * 5) + 20
    let targetLabel = UILabel(frame: CGRect(x: CGFloat(xAxis), y: CGFloat(yAxis), width: CGFloat(targetWidth), height: targetHeigt))

        ...
}
</code>```

答:
for arrayIndex in stride(from: ansWithoutSpaces.count - 1, through: 0, by: -1) {
    x = ansWithoutSpaces[arrayIndex]
}
```

Title: Reversing CGRect - Swift

Body:
How can I reverse my origin.x? my origin.x started from right I want start from left. For example these origins of x in my application started from the far right:

1) 351.0

2) 304.0

3) 257.0

4) 210.0

5) 163.0

6) 116.0

7) 69.0

8) 22.0

How can I reverse these origins and started from 22.0 and end to 351.0 ?

Code:

var ansWithoutSpaces = String()
ansWithoutSpaces = answersString.replacingOccurrences(of: " ", with: "")

var targetHeigt = CGFloat()
let viewWidth = self.view.frame.size.width

if viewWidth == 320 {
    targetHeigt = 2.5
} else {
    targetHeigt = 5
}

let yAxis : Int = Int((self.view.frame.height) * 60%)
let lenghtOfChar = ansWithoutSpaces as NSString
// char count
let width: Int = Int(view.frame.size.width) - 40
// frame width
var targetWidth: Int = (width - (lenghtOfChar.length - 1) * 5) / lenghtOfChar.length

if targetWidth > 50 {
    if viewWidth == 320 {
        targetWidth = 38
    } else if viewWidth == 375 {
        targetWidth = 45
    } else {
        targetWidth = 50
    }
}

let totalWidth: Int = (targetWidth * lenghtOfChar.length) + ((lenghtOfChar.length - 1) * 5)

for x in 0..<ansWithoutSpaces.count {
    let xAxis: Int = (width / 2) - (totalWidth / 2) + (x * targetWidth) + (x * 5) + 20
    let targetLabel = UILabel(frame: CGRect(x: CGFloat(xAxis), y: CGFloat(yAxis), width: CGFloat(targetWidth), height: targetHeigt))

        ...
}


问:
Preserve key order (stable sort) when sorting with PHP's uasort
This question is actually inspired from another one here on SO and I wanted to expand it a bit.

Having an associative array in PHP is it possible to sort its values, but where the values are equal to preserve the original key order, using one (or more) of PHP's built in sort function?

Here is a script I used to test possible solutions (haven't found any):

```<code><?php
header('Content-type: text/plain');
for($i=0;$i<10;$i++){
    $arr['key-'.$i] = rand(1,5)*10;
}
uasort($arr, function($a, $b){
    // sort condition may go here //
    // Tried: return ($a == $b)?1:($a - $b); //
    // Tried: return $a >= $b; //
});
print_r($arr);
?>
</code>```

Pitfall: Because the keys are ordered in the original array, please don't be tempted to suggest any sorting by key to restore to the original order. I made the example with them ordered to be easier to visually check their order in the output.

答:
As a workaround for stable sort:

<?php
header('Content-type: text/plain');
for ($i = 0;$i < 10;$i++)
{
    $arr['key-' . $i] = rand(1, 5) * 10;
}
uksort($arr, function ($a, $b) use ($arr)
{
    if ($arr[$a] === $arr[$b]) return array_search($a, array_keys($arr)) - array_search($b, array_keys($arr));
    return $arr[$a] - $arr[$b];
});
print_r($arr);
```

Body:
This question is actually inspired from another one here on SO and I wanted to expand it a bit.

Having an associative array in PHP is it possible to sort its values, but where the values are equal to preserve the original key order, using one (or more) of PHP's built in sort function?

Here is a script I used to test possible solutions (haven't found any):

<?php
header('Content-type: text/plain');
for($i=0;$i<10;$i++){
    $arr['key-'.$i] = rand(1,5)*10;
}
uasort($arr, function($a, $b){
    // sort condition may go here //
    // Tried: return ($a == $b)?1:($a - $b); //
    // Tried: return $a >= $b; //
});
print_r($arr);
?>

Pitfall: Because the keys are ordered in the original array, please don't be tempted to suggest any sorting by key to restore to the original order. I made the example with them ordered to be easier to visually check their order in the output.


问:
Break points not behaving with scale_y_continuous()
I'm trying to plot some data where the y-values are large:

```<code>p <- seq(0.1, 0.9, 0.1)
cost <- 1/(p^2)^15 * 15 * 0.1
data <- data.frame(x=p, y=cost)
ggplot(data, aes(x=x, y=y)) +
  geom_point(shape=18, color="blue")+
  scale_y_continuous(name="Cost", breaks=c(0, 1e5, 1e10, 1e15, 1e20, 1e25, 1e30))
</code>```

When specifying the breakpoints like this, however, all the data points except the first and largest y-value are aligned with the line y=0.

See:

Suggestions?

答:
Your best bet is to rescale your data, such as here with the logarithm. You could just denote this in the labeling of your graph, and still provide un-scaled y-axis labels.

breaks = c(0, 1e5, 1e10, 1e15, 1e20, 1e25, 1e30)

ggplot(data, aes(x=x, y=log(y))) +
  geom_point(shape=18, color="blue")+
  scale_y_continuous(name = "Cost",
                     breaks = log(breaks),
                     labels = breaks)
```

<p>Even simpler, a bit rusty:</p>

<pre class="lang-r prettyprint-override"><code>ggplot(data, aes(x=x, y=y)) +
  geom_point(shape=18, color="blue")+
  scale_y_continuous(name="Cost",
                     breaks = c(0, 1e5, 1e10, 1e15, 1e20, 1e25, 1e30),
                     trans = "log")
</code>```

Body:
I'm trying to plot some data where the y-values are large:

p <- seq(0.1, 0.9, 0.1)
cost <- 1/(p^2)^15 * 15 * 0.1
data <- data.frame(x=p, y=cost)
ggplot(data, aes(x=x, y=y)) +
  geom_point(shape=18, color="blue")+
  scale_y_continuous(name="Cost", breaks=c(0, 1e5, 1e10, 1e15, 1e20, 1e25, 1e30))

When specifying the breakpoints like this, however, all the data points except the first and largest y-value are aligned with the line y=0.

See:

Suggestions?

Body:
Your best bet is to rescale your data, such as here with the logarithm. You could just denote this in the labeling of your graph, and still provide un-scaled y-axis labels.

breaks = c(0, 1e5, 1e10, 1e15, 1e20, 1e25, 1e30)

ggplot(data, aes(x=x, y=log(y))) +
  geom_point(shape=18, color="blue")+
  scale_y_continuous(name = "Cost",
                     breaks = log(breaks),
                     labels = breaks)

Even simpler, a bit rusty:

ggplot(data, aes(x=x, y=y)) +
  geom_point(shape=18, color="blue")+
  scale_y_continuous(name="Cost",
                     breaks = c(0, 1e5, 1e10, 1e15, 1e20, 1e25, 1e30),
                     trans = "log")


问:
Prevent glob from selecting a file with a specific file name
I have a folder with 5 html files. The files are called:

page-1.html

page-2.html

page-hello.html

page-32.html

yo-page-text.html

I wish to use glob function to return an array with only the files formatted: "page[number 0 - 1000]".
So essentially I wish the glob function to return the following pages from the example above:

page-1.html

page-2.html

page-32.html

This is the code that I have managed to write so far:

<?php
    $directory = "testfolder/";
    foreach (glob($directory . "page-*.html") as $filename) {
        echo basename($filename);
    }
?>
```

答:
Assuming that your code works and that you get the basename of the files:

```<code>$name = basename($filename); //do not echo the basename
for ($i = 0; $i <= 1000; $i++) {
  $trname = "page-$i";
  if ($name == $trname) {
    echo "$name";
  }
}
</code>```

Put one of these codes inside the foreach and get rid of echo basename($filename);. I'd recommend using the second one as nesting loops may prove to be a problem.

Note: This code can only work if your one works.

IMPORTANT EDIT:
My guess id that you want to do something (not echoing) the names, in which case:

```<code>function foo(bar) {
  $arr = array();
  $name = basename($filename);
  $name = str_replace("page-", "", $name);
  if (intval($name) < 1000 && intval($name) >= 0) {
    $arr[] = $name;
  }
}
</code>```

Then, you can call on the function this way:

```<code>function foo() {
$arr = array();
$directory = "testfolder/";
foreach (glob($directory . "page-*.html") as $filename) {
  $name = basename($filename);
  $name = str_replace("page-", "", $name);
  if (intval($name) < 1000 && intval($name) >= 0) {
    $arr[] = $name;
  }
}
}
$bar = foo();
foreach ($bar as $obj) {
  //do something
}
</code>```

Body:
Assuming that your code works and that you get the basename of the files:

$name = basename($filename); //do not echo the basename
for ($i = 0; $i <= 1000; $i++) {
  $trname = "page-$i";
  if ($name == $trname) {
    echo "$name";
  }
}

Put one of these codes inside the foreach and get rid of echo basename($filename);. I'd recommend using the second one as nesting loops may prove to be a problem.

Note: This code can only work if your one works.

IMPORTANT EDIT:
My guess id that you want to do something (not echoing) the names, in which case:

function foo(bar) {
  $arr = array();
  $name = basename($filename);
  $name = str_replace("page-", "", $name);
  if (intval($name) < 1000 && intval($name) >= 0) {
    $arr[] = $name;
  }
}

Then, you can call on the function this way:

function foo() {
$arr = array();
$directory = "testfolder/";
foreach (glob($directory . "page-*.html") as $filename) {
  $name = basename($filename);
  $name = str_replace("page-", "", $name);
  if (intval($name) < 1000 && intval($name) >= 0) {
    $arr[] = $name;
  }
}
}
$bar = foo();
foreach ($bar as $obj) {
  //do something
}


问:
URN Problem Forge Model Derivative API - Invalid design parameter
I'm trying to translate an object I've previously uploaded to a Forge bucket, but I'm getting a parameter error. I'm assuming the URN is the issue. I can confirm that the object is uploaded properly, as I have been able to download it from the bucket.

My code is as follows:

I use the getObjectDetails call to get the object URN as the object ID:

```<code>static getObjectUrn (oAuth2TwoLegged, objectName, callback) {
    ObjectsApi.getObjectDetails(bucketKey, objectName, {}, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials()).then((resp) => {
        callback(null, resp.body.objectId);
    }, callback);
}
</code>```

I get back something like:
urn:adsk.objects:os.object:configtest2/f8d215f7-9ff0-474a-87b9-632ca745b39eresult.zip

My request body looks like this:

```<code>let data = urn;
var buf = new Buffer(data, 'base64');
var plain_buf = buf.toString();
console.log(plain_buf);

const resolvedTemplate = {
                        'input': {
                            "urn": plain_buf,
                            "compressedUrn": true,
                            "rootFilename": self.rootFilename
                        },
                        'output': {
                            "destination": {
                              "region": "us"
                            },
                            "formats": [
                              {
                                "type": "svf",
                                "views": [
                                  "3d"
                                ]
                              }
                            ]
                          },
                    };
</code>```

I've tried a couple different variations of the urn before and after encoding it, to no avail. My root file name is PlaysetGA.iam, although this is a .zip folder, so I've also tried the path inside the folder which is Playset/PlaysetGA.iam.

I've checked out the following page:
https://forge.autodesk.com/en/docs/model-derivative/v2/tutorials/prepare-file-for-viewer/
and this question:
Model Derivative API Post Job - 400 Bad Request "Invalid 'design' parameter"

This is the response I'm getting:
{"diagnostic":"Invalid 'design' parameter."}

Obviously, I'm missing something. Thanks!

Edit:
I've updated my .zip folder so my rootfile is in the base file path. This the the root directory:

Root folder

答:
Turns out

```<code>var buf = new Buffer.from(unencoded_urn, 'ascii');
var plain_buf = buf.toString('base64');
</code>```

was the proper way to encode the URN where the unencoded_urn was retrieved from the ObjectsApi.getObjectDetails function.

Body:
I'm trying to translate an object I've previously uploaded to a Forge bucket, but I'm getting a parameter error. I'm assuming the URN is the issue. I can confirm that the object is uploaded properly, as I have been able to download it from the bucket.

My code is as follows:

I use the getObjectDetails call to get the object URN as the object ID:

static getObjectUrn (oAuth2TwoLegged, objectName, callback) {
    ObjectsApi.getObjectDetails(bucketKey, objectName, {}, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials()).then((resp) => {
        callback(null, resp.body.objectId);
    }, callback);
}

I get back something like:
urn:adsk.objects:os.object:configtest2/f8d215f7-9ff0-474a-87b9-632ca745b39eresult.zip

My request body looks like this:

let data = urn;
var buf = new Buffer(data, 'base64');
var plain_buf = buf.toString();
console.log(plain_buf);

const resolvedTemplate = {
                        'input': {
                            "urn": plain_buf,
                            "compressedUrn": true,
                            "rootFilename": self.rootFilename
                        },
                        'output': {
                            "destination": {
                              "region": "us"
                            },
                            "formats": [
                              {
                                "type": "svf",
                                "views": [
                                  "3d"
                                ]
                              }
                            ]
                          },
                    };

I've tried a couple different variations of the urn before and after encoding it, to no avail. My root file name is PlaysetGA.iam, although this is a .zip folder, so I've also tried the path inside the folder which is Playset/PlaysetGA.iam.

I've checked out the following page:
https://forge.autodesk.com/en/docs/model-derivative/v2/tutorials/prepare-file-for-viewer/
and this question:
Model Derivative API Post Job - 400 Bad Request "Invalid 'design' parameter"

This is the response I'm getting:
{"diagnostic":"Invalid 'design' parameter."}

Obviously, I'm missing something. Thanks!

Edit:
I've updated my .zip folder so my rootfile is in the base file path. This the the root directory:

Root folder

Body:
Turns out

var buf = new Buffer.from(unencoded_urn, 'ascii');
var plain_buf = buf.toString('base64');

was the proper way to encode the URN where the unencoded_urn was retrieved from the ObjectsApi.getObjectDetails function.


问:
What would cause all compiler warnings be suppressed for only 1 of multiple projects within a visual studio solution?
I have a Visual Studio 2019 solution comprising of 4 projects. For 3 of the 4 projects, warnings are reported in Visual Studio's Error List window as normal. But for 1 of the 4 projects, all compiler warnings appear to be suppressed and for this 1 project no warnings are being reported in the Error List window at all.

If I introduce an error, that is reported in the Error List window as expected, but not warnings. I have added code that I am certain should cause a warning but still no warning is reported for the affected project.

What could cause all warnings for 1 project to be suppressed? How can I get warnings turned on again for this project?

答: In Project properties > Compile tab, there is a "Disable all warnings" check box. For this 1 project in the solution it was checked. Unchecking it resolved the problem:


问:
Supress output from function
there is a thing I want to eliminate, it is when the function print to output, I know about overriding sys.stdout.write which print() function uses. but I think this isn't an ideal fix for this. I'm looking for the ideal pythonic way for doing this?

```<code>from timeit import Timer
from functools import partial

def timing_decorator(function):
    def wrapper(*args, **kwargs):
        # print(function)
        callable_f = partial(function, *args, **kwargs)
        # print(dir(Timer))
        total = Timer(callable_f).timeit(1)
        print(total)
        return total
    return wrapper

# example function
@timing_decorator
def hello(arg):
    print(arg)
    return

hello('hi')
</code>```

This outputs:

```<code>hi
0.00036
</code>```

My expected output would be:

```<code>0.00036
</code>```

答:
We can use patch from the unittest module of the standard library to override the print functionality only when calling a function that uses this wrapper by using a context-manager. However, with that being said, the approach that @kindall takes is preferred as it is more Pythonic given this answer is using something inherently meant for testing purposes.

```<code>from unittest.mock import patch

def timing_decorator(function):
    def wrapper(*args, **kwargs):
        # print(function)
        callable_f = partial(function, *args, **kwargs)
        with patch('__main__.print'):
            total = Timer(callable_f).timeit(1)
        print(f"{function.__name__}: {total:.5f}ms")
        return total
    return wrapper
</code>```

Title: Supress output from function

Body:
there is a thing I want to eliminate, it is when the function print to output, I know about overriding sys.stdout.write which print() function uses. but I think this isn't an ideal fix for this. I'm looking for the ideal pythonic way for doing this?

from timeit import Timer
from functools import partial

def timing_decorator(function):
    def wrapper(*args, **kwargs):
        # print(function)
        callable_f = partial(function, *args, **kwargs)
        # print(dir(Timer))
        total = Timer(callable_f).timeit(1)
        print(total)
        return total
    return wrapper

# example function
@timing_decorator
def hello(arg):
    print(arg)
    return

hello('hi')

This outputs:

hi
0.00036

My expected output would be:

0.00036

Body:
We can use patch from the unittest module of the standard library to override the print functionality only when calling a function that uses this wrapper by using a context-manager. However, with that being said, the approach that @kindall takes is preferred as it is more Pythonic given this answer is using something inherently meant for testing purposes.

from unittest.mock import patch

def timing_decorator(function):
    def wrapper(*args, **kwargs):
        # print(function)
        callable_f = partial(function, *args, **kwargs)
        with patch('__main__.print'):
            total = Timer(callable_f).timeit(1)
        print(f"{function.__name__}: {total:.5f}ms")
        return total
    return wrapper


问:
Design Tips for PHP Function Include Files
Good design dictates only writing each function once.  In PHP I'm doing this by using include files (like Utils.php and Authenticate.php), with the PHP command include_once.  However I haven't been able to find any standards or best practices for PHP include files.  What would you at StackOverflow suggest?

I'm looking for:

Naming Standards

Code Standards

Design Patterns

Suggestions for defining return types of common functions
(now I'm just using associative arrays).

答:
One convention I like to use is to put each class in its own file named ClassName.class.php and then set up the autoloader to include the class files. Or sometimes I'll put them all in a classes/ subdirectory and just name them ClassName.php. Depends on how many class vs. non-class includes I'm expecting.

If you organize your utility functions into classes and make them static methods instead, you can get away with writing only a single require_once() in your top level files. This approach may or may not be appropriate for your code or coding style.

As for return types, I try to follow the conventions used in the built-in functions. Return a type appropriate to the request, or return false on failure. Just make sure you use the === operator when checking for false in the results.

The fact that you're concerned about conventions suggests you're already on the right track. If you are familiar with any other OOP language like Java, C++, C#, etc., then you'll find you can follow a lot of the same conventions thanks to the OOP goodness in PHP5.

OwnerDisplayName: C. Ross

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: Ryan Graham


问:
Indexing subclass fields by IndexEmbedded
I'm am using NHibernate.Search and Lucene.Net. I will ask if anyone have experienced similar problems. This is the situation regarding the following three classes.

```<code>[Indexed]
public class File
{
    [Field]
    public virtual string FileId { get; private set; }

    [ContainedIn]
    public virtual List<Record> Records { get; private set; }
}

[Indexed]
public class CaseFile : File
{
    [Field]
    public virtual int CaseYear { get; set; }
    [Field]
    public virtual int CaseSequenceNumber { get; set; }
}

[Indexed]
public class Record
{
    [IndexedEmbedded]
    public virtual File ParentFile { get; set; }
}
</code>```

The problem is when I try to index the record class. The goal is to get all fields of both the File class and the subclass CaseFile contained in the Record index. But when I index the Record class I only get fields of the File superclass in my Record index. The fields of the CaseFile subclass are missing in the Record index.

I have also tried the [IndexedEmbedded(TargetElement = typeof(CaseFile))] on the ParentFile property in the Record class, but this leads to totally empty indexes, or no indexing at all.

If I index the File class, the expected subclass properties are indexed as expected in the File index.

Have anyone experienced similar problems with Hibernate/NHibernate search?

答:
I discussed the problem with Hibernate/NHibernate search and they confirmed that the situation is a bug.

They recommended using a custom class bridge to add the missing fields to the index I wanted it to be in.

This was much cleaner and I was satisified with this soluion until the source in Hibernate/NHibernate search is fixed.

Body:
I'm am using NHibernate.Search and Lucene.Net. I will ask if anyone have experienced similar problems. This is the situation regarding the following three classes.

[Indexed]
public class File
{
    [Field]
    public virtual string FileId { get; private set; }

    [ContainedIn]
    public virtual List<Record> Records { get; private set; }
}

[Indexed]
public class CaseFile : File
{
    [Field]
    public virtual int CaseYear { get; set; }
    [Field]
    public virtual int CaseSequenceNumber { get; set; }
}

[Indexed]
public class Record
{
    [IndexedEmbedded]
    public virtual File ParentFile { get; set; }
}

The problem is when I try to index the record class. The goal is to get all fields of both the File class and the subclass CaseFile contained in the Record index. But when I index the Record class I only get fields of the File superclass in my Record index. The fields of the CaseFile subclass are missing in the Record index.

I have also tried the [IndexedEmbedded(TargetElement = typeof(CaseFile))] on the ParentFile property in the Record class, but this leads to totally empty indexes, or no indexing at all.

If I index the File class, the expected subclass properties are indexed as expected in the File index.

Have anyone experienced similar problems with Hibernate/NHibernate search?


问:
Getting the DIFFERENT position of an elements with the same class
I have a dynamic table and each row has a menu button. These buttons share the same class. I want to get the X , Y positions of the button I click. My current attempt is using the following.

```<code>$(document).ready(function () {
    $(".actionMenu").click(function () {
        let element = this.className;
        let elementPos = $("." + element).position();
    })
})
</code>```

My problem is that this will return the FIRST item with the matching class name. Is there a way that I can get the position of the element clicked without specifying a class?

Fiddle

ANSWER

I was checking the position using the alert/console log and it was giving me the same answer each time, I tested it using an actual DIV and just changed the css and it works perfectly as intended, the div moves to the appropriate position, instead of position I used offset.

Thank you for all those who helped.

答:
I think you can do like this

```<code>$('.actionMenu').on('click', function () {
  let x_pos = $(this).position().top;
  let y_pos = $(this).position().left;
  alert("Top:"+x_pos+" Left:"+y_pos);
});
</code>```

LINK: https://jsfiddle.net/wep142Lg/2/

// From http://learn.shayhowe.com/advanced-html-css/jquery

// Change tab class and display content
$('.actionMenu').on('click', function() {
  console.log("Top:" + $(this).position().top + " Left:" + $(this).position().left);
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>table {
  border: 1px solid #222;
  width: 100%;
}

td {
  border: 1px solid #222;
}</code>```

    Row 1

      <button class="actionMenu">Button</button>

    Row 2

      <button class="actionMenu">Button</button>

    Row 3

      <button class="actionMenu">Button</button>

    Row 4

      <button class="actionMenu">Button</button>

```

Body:
I have a dynamic table and each row has a menu button. These buttons share the same class. I want to get the X , Y positions of the button I click. My current attempt is using the following.

$(document).ready(function () {
    $(".actionMenu").click(function () {
        let element = this.className;
        let elementPos = $("." + element).position();
    })
})

My problem is that this will return the FIRST item with the matching class name. Is there a way that I can get the position of the element clicked without specifying a class?

Fiddle

ANSWER

I was checking the position using the alert/console log and it was giving me the same answer each time, I tested it using an actual DIV and just changed the css and it works perfectly as intended, the div moves to the appropriate position, instead of position I used offset.

Thank you for all those who helped.

Body:
I think you can do like this

$('.actionMenu').on('click', function () {
  let x_pos = $(this).position().top;
  let y_pos = $(this).position().left;
  alert("Top:"+x_pos+" Left:"+y_pos);
});

LINK: https://jsfiddle.net/wep142Lg/2/

// From http://learn.shayhowe.com/advanced-html-css/jquery

// Change tab class and display content
$('.actionMenu').on('click', function() {
  console.log("Top:" + $(this).position().top + " Left:" + $(this).position().left);
});

table {
  border: 1px solid #222;
  width: 100%;
}

td {
  border: 1px solid #222;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>Row 1</td>
    <td>
      <button class="actionMenu">Button</button>
    </td>
  </tr>
  <tr>
    <td>Row 2</td>
    <td>
      <button class="actionMenu">Button</button>
    </td>
  </tr>
  <tr>
    <td>Row 3</td>
    <td>
      <button class="actionMenu">Button</button>
    </td>
  </tr>
  <tr>
    <td>Row 4</td>
    <td>
      <button class="actionMenu">Button</button>
    </td>
  </tr>
</table>


问:
Openapi YAML wrong, cannot generate client-stubs
I'm evaluating Quarkus as backend, accessed by an angular frontend.
I wanted to use the openapi data provided by Quarkus via http://localhost:8080/openapi,
and generate via openapi-generator tools an typescript-angular client stub.

I used as first step the Quarkus Openapi Guide: https://quarkus.io/guides/openapi-swaggerui
But after running the unmodified example and retrieve the Openapi YAML-Data via the http://localhost:8080/openapi I noticed that the generated data is wrong and the openapi generator is not able to generate a client because of a stackoverflow error.

Problem: a self-reference in the Openapi-data for the SetFruit-Definition (last line):

```<code>openapi: 3.0.1
info:
  title: Generated API
  version: "1.0"
paths:
  /fruits:
    get:
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetFruit'
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetFruit'
    delete:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetFruit'
components:
  schemas:
    Fruit:
      type: object
      properties:
        description:
          type: string
        name:
          type: string
    SetFruit:
      $ref: '#/components/schemas/SetFruit'
</code>```

Is this a known problem, or is there some misunderstanding on my side.
Is there a way to work around this issue?

Many Thanks!

答:
It should definitely not be generating a self-referencing definition!  Could you perhaps open up an issue here:

https://github.com/smallrye/smallrye-open-api/issues

That library is the implementation behind the Quarkus support for this feature.  If you could include a reproducer project that would be very helpful.  Or at the very least give us some information about the Fruit and SetFruit java classes.

Body:
I'm evaluating Quarkus as backend, accessed by an angular frontend.
I wanted to use the openapi data provided by Quarkus via http://localhost:8080/openapi,
and generate via openapi-generator tools an typescript-angular client stub.

I used as first step the Quarkus Openapi Guide: https://quarkus.io/guides/openapi-swaggerui
But after running the unmodified example and retrieve the Openapi YAML-Data via the http://localhost:8080/openapi I noticed that the generated data is wrong and the openapi generator is not able to generate a client because of a stackoverflow error.

Problem: a self-reference in the Openapi-data for the SetFruit-Definition (last line):

openapi: 3.0.1
info:
  title: Generated API
  version: "1.0"
paths:
  /fruits:
    get:
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetFruit'
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetFruit'
    delete:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetFruit'
components:
  schemas:
    Fruit:
      type: object
      properties:
        description:
          type: string
        name:
          type: string
    SetFruit:
      $ref: '#/components/schemas/SetFruit'

Is this a known problem, or is there some misunderstanding on my side.
Is there a way to work around this issue?

Many Thanks!


问:
Squaring all the elements in a list by Scheme
I wanted to square all elements in a list by the Scheme programming language.
my code is:

(define (square n) (* n *n))

(define (fun items factor)
  (if (null? items)
      0
      (cons (* (fun (car items)
                    factor))
            (fun (cdr items)
                 factor) ) ) ) )
(display (fun '( 1 2 3 4) square))
```

<p>I'm showing these errors: </p>

```ERROR: In procedure car:
  ERROR: In procedure car:
    Wrong type (expecting pair): 1
```

答:
Here is other method:</p>

```<code>(define factor-list
  (lambda (l factor return)
    (if (null? l)
        (return '())
        (factor-list (cdr l)
                     factor
                     (lambda (rest)
                       (return (cons (factor (car l))
                                     rest)))))))

(define input '(1 2 3 4))
(factor-list input (lambda (x) (* x x)) (lambda (x) x))

</code>```

Body:
I wanted to square all elements in a list by the Scheme programming language.
my code is:

(define (square n) (* n *n))

(define (fun items factor)
  (if (null? items)
      0
      (cons (* (fun (car items)
                    factor))
            (fun (cdr items)
                 factor) ) ) ) )
(display (fun '( 1 2 3 4) square))

I'm showing these errors:

ERROR: In procedure car:
  ERROR: In procedure car:
    Wrong type (expecting pair): 1

Body:
Here is other method:

(define factor-list
  (lambda (l factor return)
    (if (null? l)
        (return '())
        (factor-list (cdr l)
                     factor
                     (lambda (rest)
                       (return (cons (factor (car l))
                                     rest)))))))

(define input '(1 2 3 4))
(factor-list input (lambda (x) (* x x)) (lambda (x) x))


问:
Django Blog App urls functionality
I am trying to integrate the following blog APP https://github.com/nathanborror/django-basic-apps ,so in my main urls.py i have included the blog urls as (r'^blog/',include('basic.blog.urls')),  Now my question is that now when i point my browser to the blog APP http://127.0.0.1/blog/ i get a message as "Post archive",How to proceed from here i.e, how to post blog and retrieve the same.What is the url to be used..The following is the blog urls

```<code>from django.conf.urls.defaults import *

urlpatterns = patterns('basic.blog.views',
url(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$',
    view='post_detail',
    name='blog_detail'
),
url(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/$',
    view='post_archive_day',
    name='blog_archive_day'
),
url(r'^(?P<year>\d{4})/(?P<month>\w{3})/$',
    view='post_archive_month',
    name='blog_archive_month'
),
url(r'^(?P<year>\d{4})/$',
    view='post_archive_year',
    name='blog_archive_year'
),
url(r'^categories/(?P<slug>[-\w]+)/$',
    view='category_detail',
    name='blog_category_detail'
),
url (r'^categories/$',
    view='category_list',
    name='blog_category_list'
),
url(r'^tags/(?P<slug>[-\w]+)/$',
    view='tag_detail',
    name='blog_tag_detail'
),
url (r'^search/$',
    view='search',
    name='blog_search'
),
url(r'^page/(?P<page>\d+)/$',
    view='post_list',
    name='blog_index_paginated'
),
url(r'^$',
    view='post_list',
   name='blog_index'
),
)
</code>```

答:
I have never used this blogging app, but im guessing because it suggests its "basic" it will just provide the bare bones. So my starting point would be to add a post and see what happens.

If going to /blog/ doesnt provide a way to add a post, then register the models with your admin site and add through that way. Im guessing that you may have to build your own adding sections...

If you dont want to do this, djang-blog-zinnia is a blogging app i have used, and really like it

Title: Django Blog App urls functionality

Body:
I am trying to integrate the following blog APP https://github.com/nathanborror/django-basic-apps ,so in my main urls.py i have included the blog urls as (r'^blog/',include('basic.blog.urls')),  Now my question is that now when i point my browser to the blog APP http://127.0.0.1/blog/ i get a message as "Post archive",How to proceed from here i.e, how to post blog and retrieve the same.What is the url to be used..The following is the blog urls

from django.conf.urls.defaults import *

urlpatterns = patterns('basic.blog.views',
url(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$',
    view='post_detail',
    name='blog_detail'
),
url(r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{1,2})/$',
    view='post_archive_day',
    name='blog_archive_day'
),
url(r'^(?P<year>\d{4})/(?P<month>\w{3})/$',
    view='post_archive_month',
    name='blog_archive_month'
),
url(r'^(?P<year>\d{4})/$',
    view='post_archive_year',
    name='blog_archive_year'
),
url(r'^categories/(?P<slug>[-\w]+)/$',
    view='category_detail',
    name='blog_category_detail'
),
url (r'^categories/$',
    view='category_list',
    name='blog_category_list'
),
url(r'^tags/(?P<slug>[-\w]+)/$',
    view='tag_detail',
    name='blog_tag_detail'
),
url (r'^search/$',
    view='search',
    name='blog_search'
),
url(r'^page/(?P<page>\d+)/$',
    view='post_list',
    name='blog_index_paginated'
),
url(r'^$',
    view='post_list',
   name='blog_index'
),
)