问:
best practice for primary key constraints?
I wonder what would be best in a postgresql database when using primary keys.

IF there is a table with two UUID's columns like user1 and user2, what would be better, to use a constraint key or just define both columns as unique without any primary key, because in postgresql you can only have one primary key in a table?

Example:

```<code>CREATE TABLE user_relation(
    sender_user_id UUID NOT NULL,
    receiver_user_id UUID NOT NULL,
    status INT NOT NULL,
    chat_id BIGINT,
    UNIQUE (chat_id),
    CONSTRAINT user_relation_pk UNIQUE(sender_user_id, receiver_user_id)

</code>```

Or would it be better to just define the both 'primary keys' as unique values like that?

```<code>CREATE TABLE user_relation(
    sender_user_id UUID NOT NULL,
    receiver_user_id UUID NOT NULL,
    status INT NOT NULL,
    chat_id BIGINT,
    UNIQUE (sender_user_id, receiver_user_id, chat_id)
)
</code>```

答:
Your two table definitions are quite different.

```<code>UNIQUE(a, b, c)
</code>```

does not mean that each of these columns will be unique, but that the combination of all three will be unique (i.e., you cannot have the same triple in the table twice).

Technically speaking, a primary key is no more than a unique constraint with added NOT NULL, so it does not matter which of them you use as a primary key.

Different from many others, I do not believe that ist is always necessary to introduce an artificial primary key. As long as you are sure that

the chosen column(s) feel(s) like a “good representation” of the data.

the value for the column(s) will never change

I see no problem with using that as a primary key.

Body:
I wonder what would be best in a postgresql database when using primary keys.

IF there is a table with two UUID's columns like user1 and user2, what would be better, to use a constraint key or just define both columns as unique without any primary key, because in postgresql you can only have one primary key in a table?

Example:

CREATE TABLE user_relation(
    sender_user_id UUID NOT NULL,
    receiver_user_id UUID NOT NULL,
    status INT NOT NULL,
    chat_id BIGINT,
    UNIQUE (chat_id),
    CONSTRAINT user_relation_pk UNIQUE(sender_user_id, receiver_user_id)

Or would it be better to just define the both 'primary keys' as unique values like that?

CREATE TABLE user_relation(
    sender_user_id UUID NOT NULL,
    receiver_user_id UUID NOT NULL,
    status INT NOT NULL,
    chat_id BIGINT,
    UNIQUE (sender_user_id, receiver_user_id, chat_id)
)

Body:
Your two table definitions are quite different.

UNIQUE(a, b, c)

does not mean that each of these columns will be unique, but that the combination of all three will be unique (i.e., you cannot have the same triple in the table twice).

Technically speaking, a primary key is no more than a unique constraint with added NOT NULL, so it does not matter which of them you use as a primary key.

Different from many others, I do not believe that ist is always necessary to introduce an artificial primary key. As long as you are sure that

the chosen column(s) feel(s) like a “good representation” of the data.

the value for the column(s) will never change

I see no problem with using that as a primary key.


来源: stackexchange

问:
Interactive QDialog to show Matplotlib plot
I have a python (2.7) program (myGraph.py) which, using matplotlib creates a graph by a function showGraph().

Now from a QDialog I am calling this function showGraph() to show the graph as under:

import myGraph
# ...
# ....
class myTable(QDialog):

# ...
# ...
    myGraph.showGraph(graphName)
```

<p>The graph related to 'graphName' properly appears, but almost immediately the QDialog (myTable) reappears above the graph and I am not able to scrutinize the graph, like expanding and scrolling it. To do this I have to close the QDialog (myTable), which I don't desire. Because, I have to see different graphs passing on different graphName selecting from the QDialog.</p>

<p>So, basically I desire to select a 'graphName' from QDialog and call my matplotlib program to see the graph, scrutinize it. During this period my QDialog should be behind the graph. As soon as I close the graph the QDialog should reappear and then I would select a new 'graphName' from the dialog and scrutinize it, and so on.</p>

<p>A frame work of the programs in sequence are as below:</p>

<p>============1. Analyser.py================================</p>

```import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox
from PyQt5 import uic
from PyQt5.QtCore import QCoreApplication

Ui_MainWindwo, QtBaseClass = uic.loadUiType('analyser.ui')

class MyApp(QMainWindow):

    super(MyApp, self).__init__()
    self.ui = Ui.MainWindow()
    self.ui.setupUi(self)

    self.ui.alertPushButton.clicked.connect(self.createAlerts)

:
: ## different other signal-slot connections etc.
:

    def createAlerts(self):

:
:   ##Building up of a list 'alrtLst'
:   ##for example final alrtLst is:

        alrtLst = [['Graph1', 'Sales1-3', 'ABM', '200'],
                   ['Graph2', 'Sales4-8', 'KNT', '500'],
                   ['Graph3', 'Sales9-10', 'MT', '400'],
                   ['Graph4', 'Sales11-12', 'TSL', '500']]

        from alertTable import AlertTable
        alert_table = AlertTable(alrtLst)
        alert_table.exec_()

if __name__ == '__main__':
    app = QCoreApplcation.instance()
    if app is None:
        app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())
```

<p>============2. alertTable.py================================</p>

```from PyQt5.QtWidgets import QDialog, QTableWidgetItem
from PyQt5 import uic
import myGraph  ##myGraph.py program

class AlertTable(QDialog):
    def __init__(self, alrtLst):
        super(AlertTable, self).__init__()
        uic.loadUi('mytable.ui', self)

        self.tableWidget.doubleClicked.connect(self.tableClick)

        self.tableWidget.setColumnCount(4)
        header_labels = ['Label1', 'Label2', 'Label3', 'Label4']
        self.tableWidget.setHorizontalHeaderLabels(header_labels)

        for row in alrtLst:
            inx = alrtLst.index(row)
            self.tableWidget.insertRow(inx)
            self.tableWidget.setItem(inx,0,QTableWidgetItem(str(row[0])))
            self.tableWidget.setItem(inx,1,QTableWidgetItem(str(row[1])))
            self.tableWidget.setItem(inx,2,QTableWidgetItem(str(row[2])))
            self.tableWidget.setItem(inx,3,QTableWidgetItem(str(row[3])))

    def tableClick(self):
        row = self.tableWidget.currentItem().row()
        cell = self.tableWidget.item(row, 0),text()

        myGraph.showGraph(cell)
```

<p>============3. myGraph.py================================</p>

```import matplotlib.pyplot as plt

def showGraph(grphName):

    dfc = pd.read_csv('E:\\analyzedFiles\\'+grphName+'.csv')
    :
    : ##Construct graph
    :

plt.show()
```

<p>============4. analyzer.ui================================</p>

```<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>shareAnlyserMainWindow</class>
 <widget class="QMainWindow" name="anlyserMainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>484</width>
    <height>278</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Analyser</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout_3">
    <item row="6" column="0" colspan="3">
     <layout class="QGridLayout" name="gridLayout_2">
      <item row="0" column="0">
       <widget class="QProgressBar" name="progressBar">
        <property name="value">
         <number>24</number>
        </property>
       </widget>
      </item>
      <item row="1" column="0">
       <spacer name="verticalSpacer_3">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>40</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </item>
    <item row="0" column="0" colspan="5">
     <widget class="QLabel" name="label">
      <property name="font">

        <pointsize>28</pointsize>
        <weight>75</weight>
        <bold>true</bold>

      </property>
      <property name="text">
       <string>ANALYSER</string>
      </property>
      <property name="alignment">
       <set>Qt::AlignCenter</set>
      </property>
     </widget>
    </item>
    <item row="1" column="0" colspan="5">
     <widget class="Line" name="line">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>
    <item row="4" column="0">
     <spacer name="verticalSpacer_5">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>15</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="3" column="3" rowspan="4">
     <widget class="Line" name="line_2">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
     </widget>
    </item>
    <item row="2" column="2">
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>0</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="3" column="4" rowspan="4">
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QPushButton" name="consolidatePushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Consolidate all daily data</string>
        </property>
        <property name="text">
         <string>Consolidate</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="analysePushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Analyse each value movement</string>
        </property>
        <property name="text">
         <string>Analyse</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="alertPushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Create alerts for significant movement of specific company value</string>
        </property>
        <property name="text">
         <string>Create Alert</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="verticalSpacer_4">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>58</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="exitPushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Exit application</string>
        </property>
        <property name="text">
         <string>E&xit</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="verticalSpacer_6">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>28</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QLabel" name="label_5">
        <property name="text">
         <string>
©Bidyut
</string>
        </property>
        <property name="textFormat">
         <enum>Qt::AutoText</enum>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item row="3" column="0" colspan="3">
     <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
       <widget class="QLabel" name="label_2">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Current Month</string>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
       <widget class="QComboBox" name="monthComboBox">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <item>
         <property name="text">
          <string>Select Month ...</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>January</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>February</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>March</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>April</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>May</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>June</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>July</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>August</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>September</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>October</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>November</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>December</string>
         </property>
        </item>
       </widget>
      </item>
      <item row="0" column="2" colspan="2">
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>128</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="label_3">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Current Year</string>
        </property>
       </widget>
      </item>
      <item row="1" column="1">
       <widget class="QLineEdit" name="yearLineEdit">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
       </widget>
      </item>
      <item row="1" column="2" colspan="2">
       <spacer name="horizontalSpacer_3">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>128</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="2" column="1">
       <spacer name="verticalSpacer_2">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>13</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="3" column="0" colspan="2">
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>228</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="3" column="2">
       <widget class="QPushButton" name="enterPushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Enter</string>
        </property>
       </widget>
      </item>
      <item row="3" column="3">
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>58</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </item>
    <item row="4" column="1">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="label_4">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Selected Year Block:</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="yearBlockLabel">
        <property name="text">
         <string>xxxx-xxxx,xxxx-xxxx,xxxx-xxxx</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>484</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="actionGetValues"/>
    <addaction name="separator"/>
    <addaction name="actionExit"/>
   </widget>
   <widget class="QMenu" name="menuProcess">
    <property name="title">
     <string>Process</string>
    </property>
    <addaction name="actionConsolidate"/>
    <addaction name="actionAnalyse"/>
    <addaction name="actionCreateAlert"/>
   </widget>
   <widget class="QMenu" name="menuHelp">
    <property name="title">
     <string>Help</string>
    </property>
    <addaction name="actionAbout"/>
    <addaction name="actionTutorial"/>
   </widget>
   <widget class="QMenu" name="menuSettings">
    <property name="title">
     <string>Settings</string>
    </property>
    <addaction name="actionSetTI"/>
   </widget>
   <addaction name="menuFile"/>
   <addaction name="menuProcess"/>
   <addaction name="menuSettings"/>
   <addaction name="menuHelp"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionExit">
   <property name="text">
    <string>E&xit</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+X</string>
   </property>
  </action>
  <action name="actionConsolidate">
   <property name="text">
    <string>&Consolidate</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+Shift+C</string>
   </property>
   <property name="shortcutContext">
    <enum>Qt::ApplicationShortcut</enum>
   </property>
  </action>
  <action name="actionAnalyse">
   <property name="text">
    <string>&Analyse</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+Shift+A</string>
   </property>
  </action>
  <action name="actionCreateAlert">
   <property name="text">
    <string>Create A&lert</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+L</string>
   </property>
  </action>
  <action name="actionAbout">
   <property name="text">
    <string>A&bout</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+B</string>
   </property>
  </action>
  <action name="actionTutorial">
   <property name="text">
    <string>&Tutorial</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+T</string>
   </property>
  </action>
  <action name="actionGetValues">
   <property name="text">
    <string>GetValues</string>
   </property>
  </action>
  <action name="actionSetTI">
   <property name="text">
    <string>Technical Indicators</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>
```

<p>============5. myTable.ui================================</p>

```<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>trytable</class>
 <widget class="QDialog" name="trytable">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>551</width>
    <height>347</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Try Table</string>
  </property>
  <widget class="QWidget" name="">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>50</y>
     <width>501</width>
     <height>291</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTableWidget" name="tableWidget"/>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton">
      <property name="text">
       <string>Show Table</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="closeButton">
      <property name="text">
       <string>Close</string>
      </property>
     </widget>
    </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>18</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
```

答:
Try to change:

```<code>    alert_table = AlertTable(alrtLst)
    alert_table.exec_()
</code>```

on:

```<code>     self.alert_table = AlertTable(alrtLst)
     self.alert_table.show()         # or  open()
</code>```

```<code># Analyser.py
import sys
from PyQt5.QtCore    import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui     import *
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QPushButton
from PyQt5 import uic
from PyQt5.QtCore import QCoreApplication

from PyQt5.QtWidgets import QDialog, QTableWidgetItem
import matplotlib.pyplot as plt

import pandas as pd
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

def showGraph(grphName):
    # +++
    self.figure = plt.figure(figsize=(15,5))
    self.figure.set_facecolor('0.915')
    self.canvas = FigureCanvas(self.figure)

#    dfc = pd.read_csv('D:/_Qt/__Qt/'+grphName+'.csv')
    dfc = pd.read_csv('D:/_Qt/__Qt/grphName.csv')             #

    #    : ##Construct graph
    # plt.show()

#Ui_MainWindwo, QtBaseClass = uic.loadUiType('analyser.ui')
class AlertTable(QDialog):
    def __init__(self, alrtLst):
        super(AlertTable, self).__init__()
#        uic.loadUi('mytable.ui', self)

        self.tableWidget = QTableWidget(self)
        self.tableWidget.doubleClicked.connect(self.tableClick)

        self.tableWidget.setColumnCount(4)
        header_labels = ['Label1', 'Label2', 'Label3', 'Label4']
        self.tableWidget.setHorizontalHeaderLabels(header_labels)

        for row in alrtLst:
            inx = alrtLst.index(row)
            self.tableWidget.insertRow(inx)
            self.tableWidget.setItem(inx,0,QTableWidgetItem(str(row[0])))
            self.tableWidget.setItem(inx,1,QTableWidgetItem(str(row[1])))
            self.tableWidget.setItem(inx,2,QTableWidgetItem(str(row[2])))
            self.tableWidget.setItem(inx,3,QTableWidgetItem(str(row[3])))

        # +++
        self.figure = plt.figure(figsize=(15,5))
        self.figure.set_facecolor('0.915')
        self.canvas = FigureCanvas(self.figure)

    def tableClick(self):
        row = self.tableWidget.currentItem().row()
#        cell = self.tableWidget.item(row, 0),text()      # - ,text()
        cell = self.tableWidget.item(row, 0).text()       # + .text()

#        myGraph.showGraph(cell)
        self.showGraph(cell)

    # +++
    def showGraph(self, grphName):
        dfc, _ = QFileDialog.getOpenFileName(self, 'Open file', '/Data/', "CSV Files (*.csv)") # +++
        df = pd.read_csv(str(dfc))
        x = df.x.tolist()
        y = df.y.tolist()
        # Create Figure
        self.figure.clf()
        ax = self.figure.add_subplot(111)
        ax.plot(x, y)
        ax.set_facecolor('0.915')
        ax.set_title('Graphique')
        # Draw Graph
        self.canvas.draw()

class MyApp(QMainWindow):
    def __init__(self):
        super(MyApp, self).__init__()
#        self.ui = Ui_MainWindwo()   # Ui.MainWindow()
#        self.ui.setupUi(self)

        self.ui = self
        self.ui.alertPushButton = QPushButton("alertPushButton", self)
        self.ui.alertPushButton.clicked.connect(self.createAlerts)

    #: ## different other signal-slot connections etc.

        # +++
        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)
        layout = QVBoxLayout(centralWidget)
        layout.addWidget(self.ui.alertPushButton)

        alrtLst = [['Graph1', 'Sales1-3', 'ABM', '200'],
                   ['Graph2', 'Sales4-8', 'KNT', '500'],
                   ['Graph3', 'Sales9-10', 'MT', '400'],
                   ['Graph4', 'Sales11-12', 'TSL', '500']]
        # +++
        self.alert_table = AlertTable(alrtLst)
        layout.addWidget(self.alert_table.canvas)

    def createAlerts(self):
        #:   ##Building up of a list 'alrtLst'
        #:   ##for example final alrtLst is:

#        alert_table.exec_()                             # <<<---
        self.alert_table.show()    # or open()           # <<<---

if __name__ == '__main__':
#    app = QCoreApplcation.instance()
#    if app is None:
    app = QApplication(sys.argv)

    window = MyApp()
    window.show()
    sys.exit(app.exec_())
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a python (2.7) program (myGraph.py) which, using matplotlib creates a graph by a function showGraph().

Now from a QDialog I am calling this function showGraph() to show the graph as under:

import myGraph
# ...
# ....
class myTable(QDialog):

# ...
# ...
    myGraph.showGraph(graphName)

The graph related to 'graphName' properly appears, but almost immediately the QDialog (myTable) reappears above the graph and I am not able to scrutinize the graph, like expanding and scrolling it. To do this I have to close the QDialog (myTable), which I don't desire. Because, I have to see different graphs passing on different graphName selecting from the QDialog.

So, basically I desire to select a 'graphName' from QDialog and call my matplotlib program to see the graph, scrutinize it. During this period my QDialog should be behind the graph. As soon as I close the graph the QDialog should reappear and then I would select a new 'graphName' from the dialog and scrutinize it, and so on.

A frame work of the programs in sequence are as below:

============1. Analyser.py================================

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox
from PyQt5 import uic
from PyQt5.QtCore import QCoreApplication

Ui_MainWindwo, QtBaseClass = uic.loadUiType('analyser.ui')

class MyApp(QMainWindow):

    super(MyApp, self).__init__()
    self.ui = Ui.MainWindow()
    self.ui.setupUi(self)

    self.ui.alertPushButton.clicked.connect(self.createAlerts)

:
: ## different other signal-slot connections etc.
:

    def createAlerts(self):

:
:   ##Building up of a list 'alrtLst'
:   ##for example final alrtLst is:

        alrtLst = [['Graph1', 'Sales1-3', 'ABM', '200'],
                   ['Graph2', 'Sales4-8', 'KNT', '500'],
                   ['Graph3', 'Sales9-10', 'MT', '400'],
                   ['Graph4', 'Sales11-12', 'TSL', '500']]

        from alertTable import AlertTable
        alert_table = AlertTable(alrtLst)
        alert_table.exec_()

if __name__ == '__main__':
    app = QCoreApplcation.instance()
    if app is None:
        app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

============2. alertTable.py================================

from PyQt5.QtWidgets import QDialog, QTableWidgetItem
from PyQt5 import uic
import myGraph  ##myGraph.py program

class AlertTable(QDialog):
    def __init__(self, alrtLst):
        super(AlertTable, self).__init__()
        uic.loadUi('mytable.ui', self)

        self.tableWidget.doubleClicked.connect(self.tableClick)

        self.tableWidget.setColumnCount(4)
        header_labels = ['Label1', 'Label2', 'Label3', 'Label4']
        self.tableWidget.setHorizontalHeaderLabels(header_labels)

        for row in alrtLst:
            inx = alrtLst.index(row)
            self.tableWidget.insertRow(inx)
            self.tableWidget.setItem(inx,0,QTableWidgetItem(str(row[0])))
            self.tableWidget.setItem(inx,1,QTableWidgetItem(str(row[1])))
            self.tableWidget.setItem(inx,2,QTableWidgetItem(str(row[2])))
            self.tableWidget.setItem(inx,3,QTableWidgetItem(str(row[3])))

    def tableClick(self):
        row = self.tableWidget.currentItem().row()
        cell = self.tableWidget.item(row, 0),text()

        myGraph.showGraph(cell)

============3. myGraph.py================================

import matplotlib.pyplot as plt

def showGraph(grphName):

    dfc = pd.read_csv('E:\\analyzedFiles\\'+grphName+'.csv')
    :
    : ##Construct graph
    :

plt.show()

============4. analyzer.ui================================

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>shareAnlyserMainWindow</class>
 <widget class="QMainWindow" name="anlyserMainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>484</width>
    <height>278</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Analyser</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout_3">
    <item row="6" column="0" colspan="3">
     <layout class="QGridLayout" name="gridLayout_2">
      <item row="0" column="0">
       <widget class="QProgressBar" name="progressBar">
        <property name="value">
         <number>24</number>
        </property>
       </widget>
      </item>
      <item row="1" column="0">
       <spacer name="verticalSpacer_3">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>40</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </item>
    <item row="0" column="0" colspan="5">
     <widget class="QLabel" name="label">
      <property name="font">

        <pointsize>28</pointsize>
        <weight>75</weight>
        <bold>true</bold>

      </property>
      <property name="text">
       <string>ANALYSER</string>
      </property>
      <property name="alignment">
       <set>Qt::AlignCenter</set>
      </property>
     </widget>
    </item>
    <item row="1" column="0" colspan="5">
     <widget class="Line" name="line">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>
    <item row="4" column="0">
     <spacer name="verticalSpacer_5">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>15</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="3" column="3" rowspan="4">
     <widget class="Line" name="line_2">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
     </widget>
    </item>
    <item row="2" column="2">
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>0</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="3" column="4" rowspan="4">
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QPushButton" name="consolidatePushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Consolidate all daily data</string>
        </property>
        <property name="text">
         <string>Consolidate</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="analysePushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Analyse each value movement</string>
        </property>
        <property name="text">
         <string>Analyse</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="alertPushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Create alerts for significant movement of specific company value</string>
        </property>
        <property name="text">
         <string>Create Alert</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="verticalSpacer_4">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>58</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="exitPushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="toolTip">
         <string>Exit application</string>
        </property>
        <property name="text">
         <string>E&xit</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="verticalSpacer_6">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>28</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QLabel" name="label_5">
        <property name="text">
         <string>
&#169;Bidyut
</string>
        </property>
        <property name="textFormat">
         <enum>Qt::AutoText</enum>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item row="3" column="0" colspan="3">
     <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
       <widget class="QLabel" name="label_2">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Current Month</string>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
       <widget class="QComboBox" name="monthComboBox">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <item>
         <property name="text">
          <string>Select Month ...</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>January</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>February</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>March</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>April</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>May</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>June</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>July</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>August</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>September</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>October</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>November</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>December</string>
         </property>
        </item>
       </widget>
      </item>
      <item row="0" column="2" colspan="2">
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>128</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="label_3">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Current Year</string>
        </property>
       </widget>
      </item>
      <item row="1" column="1">
       <widget class="QLineEdit" name="yearLineEdit">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
       </widget>
      </item>
      <item row="1" column="2" colspan="2">
       <spacer name="horizontalSpacer_3">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>128</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="2" column="1">
       <spacer name="verticalSpacer_2">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>13</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="3" column="0" colspan="2">
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>228</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item row="3" column="2">
       <widget class="QPushButton" name="enterPushButton">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Enter</string>
        </property>
       </widget>
      </item>
      <item row="3" column="3">
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>58</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </item>
    <item row="4" column="1">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="label_4">
        <property name="font">

          <pointsize>10</pointsize>

        </property>
        <property name="text">
         <string>Selected Year Block:</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="yearBlockLabel">
        <property name="text">
         <string>xxxx-xxxx,xxxx-xxxx,xxxx-xxxx</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>484</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="actionGetValues"/>
    <addaction name="separator"/>
    <addaction name="actionExit"/>
   </widget>
   <widget class="QMenu" name="menuProcess">
    <property name="title">
     <string>Process</string>
    </property>
    <addaction name="actionConsolidate"/>
    <addaction name="actionAnalyse"/>
    <addaction name="actionCreateAlert"/>
   </widget>
   <widget class="QMenu" name="menuHelp">
    <property name="title">
     <string>Help</string>
    </property>
    <addaction name="actionAbout"/>
    <addaction name="actionTutorial"/>
   </widget>
   <widget class="QMenu" name="menuSettings">
    <property name="title">
     <string>Settings</string>
    </property>
    <addaction name="actionSetTI"/>
   </widget>
   <addaction name="menuFile"/>
   <addaction name="menuProcess"/>
   <addaction name="menuSettings"/>
   <addaction name="menuHelp"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionExit">
   <property name="text">
    <string>E&xit</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+X</string>
   </property>
  </action>
  <action name="actionConsolidate">
   <property name="text">
    <string>&Consolidate</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+Shift+C</string>
   </property>
   <property name="shortcutContext">
    <enum>Qt::ApplicationShortcut</enum>
   </property>
  </action>
  <action name="actionAnalyse">
   <property name="text">
    <string>&Analyse</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+Shift+A</string>
   </property>
  </action>
  <action name="actionCreateAlert">
   <property name="text">
    <string>Create A&lert</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+L</string>
   </property>
  </action>
  <action name="actionAbout">
   <property name="text">
    <string>A&bout</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+B</string>
   </property>
  </action>
  <action name="actionTutorial">
   <property name="text">
    <string>&Tutorial</string>
   </property>
   <property name="shortcut">
    <string>Ctrl+T</string>
   </property>
  </action>
  <action name="actionGetValues">
   <property name="text">
    <string>GetValues</string>
   </property>
  </action>
  <action name="actionSetTI">
   <property name="text">
    <string>Technical Indicators</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

============5. myTable.ui================================

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>trytable</class>
 <widget class="QDialog" name="trytable">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>551</width>
    <height>347</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Try Table</string>
  </property>
  <widget class="QWidget" name="">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>50</y>
     <width>501</width>
     <height>291</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTableWidget" name="tableWidget"/>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton">
      <property name="text">
       <string>Show Table</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="closeButton">
      <property name="text">
       <string>Close</string>
      </property>
     </widget>
    </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>18</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

Body:
Try to change:

    alert_table = AlertTable(alrtLst)
    alert_table.exec_()

on:

     self.alert_table = AlertTable(alrtLst)
     self.alert_table.show()         # or  open()

# Analyser.py
import sys
from PyQt5.QtCore    import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui     import *
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QPushButton
from PyQt5 import uic
from PyQt5.QtCore import QCoreApplication

from PyQt5.QtWidgets import QDialog, QTableWidgetItem
import matplotlib.pyplot as plt

import pandas as pd
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

def showGraph(grphName):
    # +++
    self.figure = plt.figure(figsize=(15,5))
    self.figure.set_facecolor('0.915')
    self.canvas = FigureCanvas(self.figure)

#    dfc = pd.read_csv('D:/_Qt/__Qt/'+grphName+'.csv')
    dfc = pd.read_csv('D:/_Qt/__Qt/grphName.csv')             #

    #    : ##Construct graph
    # plt.show()

#Ui_MainWindwo, QtBaseClass = uic.loadUiType('analyser.ui')
class AlertTable(QDialog):
    def __init__(self, alrtLst):
        super(AlertTable, self).__init__()
#        uic.loadUi('mytable.ui', self)

        self.tableWidget = QTableWidget(self)
        self.tableWidget.doubleClicked.connect(self.tableClick)

        self.tableWidget.setColumnCount(4)
        header_labels = ['Label1', 'Label2', 'Label3', 'Label4']
        self.tableWidget.setHorizontalHeaderLabels(header_labels)

        for row in alrtLst:
            inx = alrtLst.index(row)
            self.tableWidget.insertRow(inx)
            self.tableWidget.setItem(inx,0,QTableWidgetItem(str(row[0])))
            self.tableWidget.setItem(inx,1,QTableWidgetItem(str(row[1])))
            self.tableWidget.setItem(inx,2,QTableWidgetItem(str(row[2])))
            self.tableWidget.setItem(inx,3,QTableWidgetItem(str(row[3])))

        # +++
        self.figure = plt.figure(figsize=(15,5))
        self.figure.set_facecolor('0.915')
        self.canvas = FigureCanvas(self.figure)

    def tableClick(self):
        row = self.tableWidget.currentItem().row()
#        cell = self.tableWidget.item(row, 0),text()      # - ,text()
        cell = self.tableWidget.item(row, 0).text()       # + .text()

#        myGraph.showGraph(cell)
        self.showGraph(cell)

    # +++
    def showGraph(self, grphName):
        dfc, _ = QFileDialog.getOpenFileName(self, 'Open file', '/Data/', "CSV Files (*.csv)") # +++
        df = pd.read_csv(str(dfc))
        x = df.x.tolist()
        y = df.y.tolist()
        # Create Figure
        self.figure.clf()
        ax = self.figure.add_subplot(111)
        ax.plot(x, y)
        ax.set_facecolor('0.915')
        ax.set_title('Graphique')
        # Draw Graph
        self.canvas.draw()

class MyApp(QMainWindow):
    def __init__(self):
        super(MyApp, self).__init__()
#        self.ui = Ui_MainWindwo()   # Ui.MainWindow()
#        self.ui.setupUi(self)

        self.ui = self
        self.ui.alertPushButton = QPushButton("alertPushButton", self)
        self.ui.alertPushButton.clicked.connect(self.createAlerts)

    #: ## different other signal-slot connections etc.

        # +++
        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)
        layout = QVBoxLayout(centralWidget)
        layout.addWidget(self.ui.alertPushButton)

        alrtLst = [['Graph1', 'Sales1-3', 'ABM', '200'],
                   ['Graph2', 'Sales4-8', 'KNT', '500'],
                   ['Graph3', 'Sales9-10', 'MT', '400'],
                   ['Graph4', 'Sales11-12', 'TSL', '500']]
        # +++
        self.alert_table = AlertTable(alrtLst)
        layout.addWidget(self.alert_table.canvas)

    def createAlerts(self):
        #:   ##Building up of a list 'alrtLst'
        #:   ##for example final alrtLst is:

#        alert_table.exec_()                             # <<<---
        self.alert_table.show()    # or open()           # <<<---

if __name__ == '__main__':
#    app = QCoreApplcation.instance()
#    if app is None:
    app = QApplication(sys.argv)

    window = MyApp()
    window.show()
    sys.exit(app.exec_())


问:
How to fix this text problem in mail newsletter?
The text of every rss in the newsletter is going down and positioned to the left.

I tried to change to put two columns in order to avoid it, but then i'm couldn't get to change the column size and the text wrap down in mobile version.

                    Become an expert

                         Discover new opportunities

```

In the next link you can view that the text is going down and not aligned with the first part of text: https://i.imgur.com/Pez3jGp.png

答:
HTML code has changed a lot from how it started out 20 years ago.

At the beginning (20 years ago), we made tables. Tables for everything. These days we use
 tags and  tags - but back then, everything was in a table structure. To position things precisely, we put <tables> inside
 cells. That is what you must still do - for emails only.:

```<code><table>
   <tr>
      <td>
         <table><tr><td>some data</td></tr></table>
      </td>
   </tr>
</table>
</code>```

Also, tables in email support only limited CSS. And your CSS cannot be inside
```

References:

https://www.w3schools.com/html/html_tables.asp

https://www.sitepoint.com/how-to-code-html-email-newsletters/

https://emailmonks.com/blog/email-coding/step-step-guide-create-html-email/

Body:
The text of every rss in the newsletter is going down and positioned to the left.

I tried to change to put two columns in order to avoid it, but then i'm couldn't get to change the column size and the text wrap down in mobile version.

                    Become an expert

                         Discover new opportunities

In the next link you can view that the text is going down and not aligned with the first part of text: https://i.imgur.com/Pez3jGp.png

Body:
HTML code has changed a lot from how it started out 20 years ago.

At the beginning (20 years ago), we made tables. Tables for everything. These days we use <div> tags and <aside> tags - but back then, everything was in a table structure. To position things precisely, we put <tables> inside <table> cells. That is what you must still do - for emails only.:

<table>
   <tr>
      <td>
         <table><tr><td>some data</td></tr></table>
      </td>
   </tr>
</table>

Also, tables in email support only limited CSS. And your CSS cannot be inside <style> tags - it must be inline, like this:

<td style="text-align:right">

Not like this:

<style>
    td{text-align:right;}
</style>

References:

https://www.w3schools.com/html/html_tables.asp

https://www.sitepoint.com/how-to-code-html-email-newsletters/

https://emailmonks.com/blog/email-coding/step-step-guide-create-html-email/


问:
Mercurial: What is the difference between hg revert --all and hg up -C?
In Mercurial, what is the difference between

```<code>hg revert --all
</code>```

and

```<code>hg up -C?
</code>```

It seems that both commands revert all changes. But what is the difference?

答:
with hg up you actually switch to another revision (possibly abandoning your current branch)

with hg revert --all you change all files to be the same as in another revision, but remaining on you current working directory (and branch), meaning you can proceed with commit, or modify a couple of stuff before making such commit

it is more common to hg revert one single file, and that is why when you revert them all Mercurial asks you whether you are sure about that, or else want to perform an update instead

Body:
In Mercurial, what is the difference between

hg revert --all

and

hg up -C?

It seems that both commands revert all changes. But what is the difference?


问:
bash aliases set in while loop not persisting
Okay, I've written a shell script to read a file with the format:

shortcut1 /path/to/directory1

shortcut2 /path/to/directory2

and its supposed to read the file and build aliases such that typing shortcut1 cd's me into the mapped directory. The problem is, any of the aliases set in the loop don't persist outside of the script.

Firstly I tried just running the script.

. ./build_shortcuts.sh "~/.shortcuts"

where the file ~/.shortcuts contains

dl    ~/Downloads

  music /music

  dtop  ~/Desktop

This didn't work. Then I tried setting some aliases outside of the loop. Such as alias hello='world'; alias world='hellob'. I reran the script, typed alias to get a list of aliases and it did include hello and world as aliases, but not any of those set in the loop.

Then I thought maybe the loop isn't setting them at all, so I added alias as the final command in the script so it would print out the aliases at the end; in this case it did include the aliases but they still didn't persist in my session.

build_shortcuts.sh

script="$(cat $@ | sed -r -e 's/#[A-Za-z0-9 ]*$//' -e '/^\s+/s/^\s+//' -e '/^\s*$/d' -)"
# strip comments, entry level indentation & empty lines (in that order) from filestream

echo "${script}" | while read shortcut; do
    cut=$(echo  "${shortcut}" | awk '{         print $1 }')
    dest=$(echo "${shortcut}" | awk '{ $1=nil; print $0 }')
    dest="${dest:1}" # trim leading whitespace character

    alias "${cut}" &>/dev/null

    if [ $? = 0 ]; then
        echo "Warning: shortcut \"${cut}\" already exists" >&2
        continue # by default, skip overwriting shortcuts
    fi

    echo alias ${cut}="'cd ${dest}'"
    alias "${cut}"="'cd ${dest}'"
done

```

I want the aliases set in the loop within the script to exist outside of the script. Currently they don't.

I'm running on "GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu)" on arch linux.

答:
From the Bash manual page (the section on Pipelines):

Each command in a pipeline is executed as a separate process (i.e., in a subshell)

Since the loop is done as part of a pipe, it will be a subshell, and the alias command you do in the subshell will only be set for that subshell.

A possible work-around would be to save the aliases to a list, and then perform the actual alias commands in a second loop, a loop which is not part of a pipe or a subshell.

Body:
Okay, I've written a shell script to read a file with the format:

shortcut1 /path/to/directory1

shortcut2 /path/to/directory2

and its supposed to read the file and build aliases such that typing shortcut1 cd's me into the mapped directory. The problem is, any of the aliases set in the loop don't persist outside of the script.

Firstly I tried just running the script.

. ./build_shortcuts.sh "~/.shortcuts"

where the file ~/.shortcuts contains

dl    ~/Downloads

  music /music

  dtop  ~/Desktop

This didn't work. Then I tried setting some aliases outside of the loop. Such as alias hello='world'; alias world='hellob'. I reran the script, typed alias to get a list of aliases and it did include hello and world as aliases, but not any of those set in the loop.

Then I thought maybe the loop isn't setting them at all, so I added alias as the final command in the script so it would print out the aliases at the end; in this case it did include the aliases but they still didn't persist in my session.

build_shortcuts.sh

script="$(cat $@ | sed -r -e 's/#[A-Za-z0-9 ]*$//' -e '/^\s+/s/^\s+//' -e '/^\s*$/d' -)"
# strip comments, entry level indentation & empty lines (in that order) from filestream

echo "${script}" | while read shortcut; do
    cut=$(echo  "${shortcut}" | awk '{         print $1 }')
    dest=$(echo "${shortcut}" | awk '{ $1=nil; print $0 }')
    dest="${dest:1}" # trim leading whitespace character

    alias "${cut}" &>/dev/null

    if [ $? = 0 ]; then
        echo "Warning: shortcut \"${cut}\" already exists" >&2
        continue # by default, skip overwriting shortcuts
    fi

    echo alias ${cut}="'cd ${dest}'"
    alias "${cut}"="'cd ${dest}'"
done

I want the aliases set in the loop within the script to exist outside of the script. Currently they don't.

I'm running on "GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu)" on arch linux.


问:
urllib and "SSL: CERTIFICATE_VERIFY_FAILED" Error
I am getting the following error:

```<code>Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in        __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in  run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
</code>```

This is the code that is causing this error:

```<code>if input.startswith("!web"):
    input = input.replace("!web ", "")
    url = "https://domainsearch.p.mashape.com/index.php?name=" + input
    req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
    info = urllib2.urlopen(req).read()
    Message.Chat.SendMessage ("" + info)
</code>```

The API I'm using requires me to use HTTPS. How can I make it bypass the verification?

答:
Already lots of answers here, but we ran into this in a very specific case and blew a lot of time investigating, so adding yet another one. We saw it in the following case:

In a debian-stretch-slim docker container

Default Python 3.5.3 easy_install3

For LetsEncrypt certificates registered using cert-manager in our Kubernetes cluster

pip3 and openssl command line were both able to verify the cert and easy_install3 was able to verify other LetsEncrypt certs successfully.

The workaround was to build the latest Python (3.7.3 at the time) from source. The instructions here are detailed and easy to follow.

Body:
I am getting the following error:

Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in        __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in  run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>

This is the code that is causing this error:

if input.startswith("!web"):
    input = input.replace("!web ", "")
    url = "https://domainsearch.p.mashape.com/index.php?name=" + input
    req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
    info = urllib2.urlopen(req).read()
    Message.Chat.SendMessage ("" + info)

The API I'm using requires me to use HTTPS. How can I make it bypass the verification?


问:
PHP Function pt_register
I'm a beginner with PHP, I was exposed to processed HTML forms and I'm learning how to use it to do more and more...

I'm using this function (and based on Google so are a lot of people) but I really want to understand what it's doing....

```<code>function pt_register()
{
  $num_args = func_num_args();
   $vars = array();

   if ($num_args >= 2) {
       $method = strtoupper(func_get_arg(0));

       if (($method != 'SESSION') && ($method != 'GET') && ($method != 'POST') && ($method != 'SERVER') && ($method != 'COOKIE') && ($method != 'ENV')) {
           die('The first argument of pt_register must be one of the following: GET, POST, SESSION, SERVER, COOKIE, or ENV');
     }

       $varname = "HTTP_{$method}_VARS";
      global ${$varname};

       for ($i = 1; $i < $num_args; $i++) {
           $parameter = func_get_arg($i);

           if (isset(${$varname}[$parameter])) {
               global $$parameter;
               $$parameter = ${$varname}[$parameter];
          }

       }

   } else {
       die('You must specify at least two arguments');
   }

}
</code>```

Can anyone walk through this in English for me?

答:
Ow my,

That looks like a code snipped that replaces the deprecated register_globals setting.

Back in PHP4, all kind over user generated arguments where directly created as variables in your normal variable scope.

In plain English this means that a call to index.php?test=helloWorld would result in

```<code><?php
  echo "$test<br/>";
?>
</code>```

outputting:

```<code>helloWorld<br/>
</code>```

This is considered to be a mayor chance for programmers to shoot themselves in the foot. it has since been abolished. And for good reason.

Consider the following code:

```<code><?php

if ( isAuthorised($userId, $sessionId) ) {
   $hasAccess = true;
}
// some lines
// of code...

if ( $hasAccess ) {
    echo 'sensitive information';
}

?>
</code>```

and what whould happen if you would call this with index.php?hasAccess=1

That's right, the evil person calling your script has just gained access to the part that is for authorised users only.

In summary

It is a function that mimics the behaviour of functionality that is no longer used (since PHP5) because it was considered a major security risk.

Instead of using the code above, you should access the user supplied arguments like

```<code><?php
    echo $_GET['test'].'<br />';
?>
</code>```

Hope this helps :)

OwnerDisplayName: HaArD

ContentLicense: CC BY-SA 2.5

Title: PHP Function pt_register

Body:
I'm a beginner with PHP, I was exposed to processed HTML forms and I'm learning how to use it to do more and more...

I'm using this function (and based on Google so are a lot of people) but I really want to understand what it's doing....

function pt_register()
{
  $num_args = func_num_args();
   $vars = array();

   if ($num_args >= 2) {
       $method = strtoupper(func_get_arg(0));

       if (($method != 'SESSION') && ($method != 'GET') && ($method != 'POST') && ($method != 'SERVER') && ($method != 'COOKIE') && ($method != 'ENV')) {
           die('The first argument of pt_register must be one of the following: GET, POST, SESSION, SERVER, COOKIE, or ENV');
     }

       $varname = "HTTP_{$method}_VARS";
      global ${$varname};

       for ($i = 1; $i < $num_args; $i++) {
           $parameter = func_get_arg($i);

           if (isset(${$varname}[$parameter])) {
               global $$parameter;
               $$parameter = ${$varname}[$parameter];
          }

       }

   } else {
       die('You must specify at least two arguments');
   }

}

Can anyone walk through this in English for me?

LastEditorDisplayName: RoBorg

Body:
Ow my,

That looks like a code snipped that replaces the deprecated register_globals setting.

Back in PHP4, all kind over user generated arguments where directly created as variables in your normal variable scope.

In plain English this means that a call to index.php?test=helloWorld would result in

<?php
  echo "$test<br/>";
?>

outputting:

helloWorld<br/>

This is considered to be a mayor chance for programmers to shoot themselves in the foot. it has since been abolished. And for good reason.

Consider the following code:

<?php

if ( isAuthorised($userId, $sessionId) ) {
   $hasAccess = true;
}
// some lines
// of code...

if ( $hasAccess ) {
    echo 'sensitive information';
}

?>

and what whould happen if you would call this with index.php?hasAccess=1

That's right, the evil person calling your script has just gained access to the part that is for authorised users only.

In summary

It is a function that mimics the behaviour of functionality that is no longer used (since PHP5) because it was considered a major security risk.

Instead of using the code above, you should access the user supplied arguments like

<?php
    echo $_GET['test'].'<br />';
?>

Hope this helps :)

OwnerDisplayName: Jacco

LastEditorDisplayName: Jacco


问:
How would I add an annotation to exclude a method from a jacoco code coverage report?
I have some code in Java that I want to exclude from code coverage. How would I do this? I want to be able to add an annotation. Is there a way to configure or extend jacoco (as used in gradle) to use this?

Example:

```<code>public class Something
{
    @ExcludeFromCodeCoverage
    public void someMethod() {}
}
</code>```

答:
Tl;dr

Use annotation @lombok.Generated from Lombok.

Explanation

Jacoco integrates with Lombok. Code generated by Lombok is excluded from Jacoco coverage by default (see Release 0.8.0 in Jacoco changelog). You can misuse lombok.Generated at your method for it being excluded from the coverage report.

ContentLicense: CC BY-SA 3.0

Body:
I have some code in Java that I want to exclude from code coverage. How would I do this? I want to be able to add an annotation. Is there a way to configure or extend jacoco (as used in gradle) to use this?

Example:

public class Something
{
    @ExcludeFromCodeCoverage
    public void someMethod() {}
}


问:
How to adjust panning while zooming
I want to pan while zooming into a Mandelbrot set so that the fractal portion of the function stays within the window. The code outputs a series of png images to later be made into a video. Right now, I have the zooming and panning working but I do not know how to adjust the panning while the function is zooming.

```<code>import numpy as np
import matplotlib.pyplot as plt
from os import path

#6:36 @2560x1440 500 iter
#2:51 @2560x1440 200 iter
#0:56 @2560x1440 50 iter
#1:35 @2560x1440 100 iter
#0:53 @1920x1080 100 iter
#0:24 @1280x720  100 iter -> run overnight to generate 1000pngs
#make a video out of images in blender

#resolution
col=720
rows=1280

#initial window
x1=0.24#-0.78#-2#this initial window captures the whole Mandelbrot
x2=0.39#-0.73#1
y1=-0.1#0.03#-1
y2=0.08#0.13#1
#DON'T FORGET TO CHANGE THE OUTPATH!!!
outpath='C:\Users\yourfilepath\Seahorse valley'
#run at n=1000 overnight
for k in range(3): #generates n images (WARNING: this can take a while for n>5 at high res)
    zoom=0.1
    def mandelbrot(x,c,maxiter):
        c=complex(x,c) #x+ci
        z=0.0j #j is python for imaginary numbers (i)

        for i in range(maxiter):
           z=z**2+c #change power of z to generate other epicycloids
           if(z.real*z.real+z.imag*z.imag)>=4:
               return i
        return maxiter

    result=np.zeros([rows,col])
    for rowindex, x in enumerate(np.linspace(x1,x2,num=rows)):
        for colindex, c in enumerate(np.linspace(y1,y2,num=col)):
            result[rowindex,colindex]=mandelbrot(x,c,40)

    plt.figure()
    plt.imshow(result.T, cmap='jet_r') #[x1,x2,y1,y2])
    plt.title('Mandelbrot')
    plt.xlabel('Real C')
    plt.ylabel('Complex C')
    plt.savefig(path.join(outpath,'Seahorse {0}.png'.format(k)),dpi=1000)

    #zooms in for the next image.
    x1=x1+zoom #Change the zoom per iteration
    x2=x2-zoom #changing individial values allows for panning
    y1=y1+zoom #need to figure out how to adjust pan to stay on fractal
    y2=y2-zoom
    zoom+=zoom/2

#elephant valley coordinates in here
#(0.24,0.39,num=rows)
#(-0.1,0.08,num=col)

#coords for seahorse valley
#(-0.78,-0.73,num=rows)
#(0.03,0.13,num=col)
</code>```

I can zoom and pan, but how do I automate the panning to stay focused on the fractal? I want to run this code while I am sleeping.

答:
I see more ways to achieve this

predetermined location

Use predetermined path that leads somewhere. But for that you would need to first zoom in manually to some interesting location and then just interpolate position and zoom from start view to target view.

Of coarse for unknown target location (not precomputed) is this not possible.

For example try to zoom to this location:

```<code>x  = 0.267334004847543;
y  =-0.102419298460876;
</code>```

it is nice spiral like target aligned up to zoom 1.0e14here screenshot:

you can use specific locations in fractal which due to symmetry is always inside fractal ...

for example center on (-0.75,0.0):

Lock onto some kind of feature and pan it to predetermined location of view

For example detect area that contains specified ratio between boundary and colored pixels and pan it to some fixed view position (like center or whatever).

The feature can be anything but I would advise to avoid shape detection as this kind of fractal tent to change the shape of itself in zooms and pans to wild shapes one would not expect at start...

Title: How to adjust panning while zooming

Body:
I want to pan while zooming into a Mandelbrot set so that the fractal portion of the function stays within the window. The code outputs a series of png images to later be made into a video. Right now, I have the zooming and panning working but I do not know how to adjust the panning while the function is zooming.

import numpy as np
import matplotlib.pyplot as plt
from os import path

#6:36 @2560x1440 500 iter
#2:51 @2560x1440 200 iter
#0:56 @2560x1440 50 iter
#1:35 @2560x1440 100 iter
#0:53 @1920x1080 100 iter
#0:24 @1280x720  100 iter -> run overnight to generate 1000pngs
#make a video out of images in blender

#resolution
col=720
rows=1280

#initial window
x1=0.24#-0.78#-2#this initial window captures the whole Mandelbrot
x2=0.39#-0.73#1
y1=-0.1#0.03#-1
y2=0.08#0.13#1
#DON'T FORGET TO CHANGE THE OUTPATH!!!
outpath='C:\Users\yourfilepath\Seahorse valley'
#run at n=1000 overnight
for k in range(3): #generates n images (WARNING: this can take a while for n>5 at high res)
    zoom=0.1
    def mandelbrot(x,c,maxiter):
        c=complex(x,c) #x+ci
        z=0.0j #j is python for imaginary numbers (i)

        for i in range(maxiter):
           z=z**2+c #change power of z to generate other epicycloids
           if(z.real*z.real+z.imag*z.imag)>=4:
               return i
        return maxiter

    result=np.zeros([rows,col])
    for rowindex, x in enumerate(np.linspace(x1,x2,num=rows)):
        for colindex, c in enumerate(np.linspace(y1,y2,num=col)):
            result[rowindex,colindex]=mandelbrot(x,c,40)

    plt.figure()
    plt.imshow(result.T, cmap='jet_r') #[x1,x2,y1,y2])
    plt.title('Mandelbrot')
    plt.xlabel('Real C')
    plt.ylabel('Complex C')
    plt.savefig(path.join(outpath,'Seahorse {0}.png'.format(k)),dpi=1000)

    #zooms in for the next image.
    x1=x1+zoom #Change the zoom per iteration
    x2=x2-zoom #changing individial values allows for panning
    y1=y1+zoom #need to figure out how to adjust pan to stay on fractal
    y2=y2-zoom
    zoom+=zoom/2

#elephant valley coordinates in here
#(0.24,0.39,num=rows)
#(-0.1,0.08,num=col)

#coords for seahorse valley
#(-0.78,-0.73,num=rows)
#(0.03,0.13,num=col)

I can zoom and pan, but how do I automate the panning to stay focused on the fractal? I want to run this code while I am sleeping.

Body:
I see more ways to achieve this

predetermined location

Use predetermined path that leads somewhere. But for that you would need to first zoom in manually to some interesting location and then just interpolate position and zoom from start view to target view.

Of coarse for unknown target location (not precomputed) is this not possible.

For example try to zoom to this location:

x  = 0.267334004847543;
y  =-0.102419298460876;

it is nice spiral like target aligned up to zoom 1.0e14here screenshot:

you can use specific locations in fractal which due to symmetry is always inside fractal ...

for example center on (-0.75,0.0):

Lock onto some kind of feature and pan it to predetermined location of view

For example detect area that contains specified ratio between boundary and colored pixels and pan it to some fixed view position (like center or whatever).

The feature can be anything but I would advise to avoid shape detection as this kind of fractal tent to change the shape of itself in zooms and pans to wild shapes one would not expect at start...


问:
fsockopen fgets for only a few seconds and close. Dont wait for full byte count. Just read for a few seconds
I have the following code

It essentially connects to a local server , sends a command and reads the data back (128bytes.)
However, Sometimes its 1000 bytes, others its 4 bytes.

How can I get it so it just reads for a few seconds and closes then outputs the data it received?

I cant find anything on google to do this.
The server just sends the data and then essentially goes silent (no disconnect etc) so i just want to read for a few seconds into a variable and thats it.

```<code><?php
$fp = fsockopen("localhost", 3332, $errno, $errstr, 3);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    fwrite($fp, "FSBC004000");

        echo fgets($fp, 128);

    fclose($fp);
}
}
?>
</code>```

答:
Figured it out!

ALways the case! Spend days looking for the answer.. Post to Stackoverflow... answer it myself within minutes,. ffs

Need to use:
stream_set_timeout($fp, 2);

Body:
I have the following code

It essentially connects to a local server , sends a command and reads the data back (128bytes.)
However, Sometimes its 1000 bytes, others its 4 bytes.

How can I get it so it just reads for a few seconds and closes then outputs the data it received?

I cant find anything on google to do this.
The server just sends the data and then essentially goes silent (no disconnect etc) so i just want to read for a few seconds into a variable and thats it.

<?php
$fp = fsockopen("localhost", 3332, $errno, $errstr, 3);
if (!$fp) {
    echo "$errstr ($errno)
\n";
} else {
    fwrite($fp, "FSBC004000");

        echo fgets($fp, 128);

    fclose($fp);
}
}
?>


问:
Read n lines at a time using Bash
I read the help read page, but still don't quite make sense. Don't know which option to use.

How can I read N lines at a time using Bash?

答:
After having looked at all the answers, I think the following is the simplest, ie more scripters would understand it better than any other solution, but only for small number of items:

```<code>while read -r var1 && read -r var2; do
    echo "$var1" "$var2"
done < yourfile.txt
</code>```

The multi-command approach is also excellent, but it is lesser known syntax, although still intuitive:

```<code>while read -r var1; read -r var2; do
    echo "$var1" "$var2"
done < yourfile.txt
</code>```

It has the advantage that you don't need line continuations for larger number of items:

```<code>while
    read -r var1
    read -r var2
    ...
    read -r varN
do
    echo "$var1" "$var2"
done < yourfile.txt
</code>```

The xargs answer posted is also nice in theory, but in practice processing the combined lines is not so obvious. For example one solution I came up with using this technique is:

```<code>while read -r var1 var2; do
    echo "$var1" "$var2"
done <<< $(cat yourfile.txt | xargs -L 2 )
</code>```

but again this uses the lesser known <<< operator. However this approach has the advantage that if your script was initially

```<code>while read -r var1; do
    echo "$var1"
done <<< yourfile.txt
</code>```

then extending it for multiple lines is somewhat natural:

```<code>while read -r var1 var2; do
    echo "$var1" "$var2"
done <<< $(cat endpoints.txt | xargs -L 2 )
</code>```

The straightforward solution

```<code>while read -r var1; do
    read -r var2
    echo "$var1" "$var2"
done < yourfile.txt
</code>```

is the only other one that I would consider among the many given, for its simplicity, but syntactically it is not as expressive; compared to the && version or multi-command version it does not feel as right.

Title: Read n lines at a time using Bash

Body:
After having looked at all the answers, I think the following is the simplest, ie more scripters would understand it better than any other solution, but only for small number of items:

while read -r var1 && read -r var2; do
    echo "$var1" "$var2"
done < yourfile.txt

The multi-command approach is also excellent, but it is lesser known syntax, although still intuitive:

while read -r var1; read -r var2; do
    echo "$var1" "$var2"
done < yourfile.txt

It has the advantage that you don't need line continuations for larger number of items:

while
    read -r var1
    read -r var2
    ...
    read -r varN
do
    echo "$var1" "$var2"
done < yourfile.txt

The xargs answer posted is also nice in theory, but in practice processing the combined lines is not so obvious. For example one solution I came up with using this technique is:

while read -r var1 var2; do
    echo "$var1" "$var2"
done <<< $(cat yourfile.txt | xargs -L 2 )

but again this uses the lesser known <<< operator. However this approach has the advantage that if your script was initially

while read -r var1; do
    echo "$var1"
done <<< yourfile.txt

then extending it for multiple lines is somewhat natural:

while read -r var1 var2; do
    echo "$var1" "$var2"
done <<< $(cat endpoints.txt | xargs -L 2 )

The straightforward solution

while read -r var1; do
    read -r var2
    echo "$var1" "$var2"
done < yourfile.txt

is the only other one that I would consider among the many given, for its simplicity, but syntactically it is not as expressive; compared to the && version or multi-command version it does not feel as right.


问:
Is there any available panel to store machine learning models and their config files in a structured manner?
Saving different models with their corresponding config files, tracking the results and parameters, searching among them using customized filters and maybe always having a pointer to the current SOTA can be quite time-saving.

I couldn't even find something similar to TensorFlow Hub on the local server. Right now, closest I could get is Git LFS.

Is there anything better out there?

答: Microsoft Azure has a service called Azure Machine Learnig service that does exactly this, but goes much further with governance/model explainability/DevOps etc.  We also include free tiers to a lot of services and announced unlimited private repos on GitHub recently.</p>


问:
An algorithm to find bounding box of closed bezier curves?
I'm looking for an algorithm to find bounding box (max/min points) of a closed quadratic bezier curve in Cartesian axis:

```<code>input: C (a closed bezier curve)
output: A B C D points
</code>```

Image http://www.imagechicken.com/uploads/1270586513022388700.jpg

Note: above image shows a smooth curve. it could be not smooth. (have corners)

答:
Timo-s first variant adapted to Objective-C</p>

```<code>CGPoint CubicBezierPointAt(CGPoint p1, CGPoint p2, CGPoint p3, CGPoint p4, CGFloat t) {

   CGFloat x = CubicBezier(p1.x, p2.x, p3.x, p4.x, t);
   CGFloat y = CubicBezier(p1.y, p2.y, p3.y, p4.y, t);

   return CGPointMake(x, y);
}

// array containing TopLeft and BottomRight points for curve`s enclosing bounds
NSArray* CubicBezierExtremums(CGPoint p1, CGPoint p2, CGPoint p3, CGPoint p4) {

   CGFloat a, b, c, t, t1, t2, b2ac, sqrtb2ac;
   NSMutableArray *tValues = [NSMutableArray new];

   for (int i = 0; i < 2; i++) {
      if (i == 0) {
         a = 3 * (-p1.x + 3 * p2.x - 3 * p3.x + p4.x);
         b = 6 * (p1.x - 2 * p2.x +  p3.x);
         c = 3 * (p2.x - p1.x);
      }
      else {
         a = 3 * (-p1.y + 3 * p2.y - 3 * p3.y + p4.y);
         b = 6 * (p1.y - 2 * p2.y +  p3.y);
         c = 3 * (p2.y - p1.y);
      }

      if(ABS(a) < CGFLOAT_MIN) {// Numerical robustness
         if (ABS(b) < CGFLOAT_MIN) {// Numerical robustness
            continue;
         }

         t = -c / b;

         if (t > 0 && t < 1) {
            [tValues addObject:[NSNumber numberWithDouble:t]];
         }
         continue;
      }

      b2ac = pow(b, 2) - 4 * c * a;

      if (b2ac < 0) {
         continue;
      }

      sqrtb2ac = sqrt(b2ac);

      t1 = (-b + sqrtb2ac) / (2 * a);

      if (t1 > 0.0 && t1 < 1.0) {
         [tValues addObject:[NSNumber numberWithDouble:t1]];
      }

      t2 = (-b - sqrtb2ac) / (2 * a);

      if (t2 > 0.0 && t2 < 1.0) {
         [tValues addObject:[NSNumber numberWithDouble:t2]];
      }
   }

   int j = (int)tValues.count;

   CGFloat x = 0;
   CGFloat y = 0;
   NSMutableArray *xValues = [NSMutableArray new];
   NSMutableArray *yValues = [NSMutableArray new];

   while (j--) {
      t = [[tValues objectAtIndex:j] doubleValue];
      x = CubicBezier(p1.x, p2.x, p3.x, p4.x, t);
      y = CubicBezier(p1.y, p2.y, p3.y, p4.y, t);
      [xValues addObject:[NSNumber numberWithDouble:x]];
      [yValues addObject:[NSNumber numberWithDouble:y]];
   }

   [xValues addObject:[NSNumber numberWithDouble:p1.x]];
   [xValues addObject:[NSNumber numberWithDouble:p4.x]];
   [yValues addObject:[NSNumber numberWithDouble:p1.y]];
   [yValues addObject:[NSNumber numberWithDouble:p4.y]];

   //find minX, minY, maxX, maxY
   CGFloat minX = [[xValues valueForKeyPath:@"@min.self"] doubleValue];
   CGFloat minY = [[yValues valueForKeyPath:@"@min.self"] doubleValue];
   CGFloat maxX = [[xValues valueForKeyPath:@"@max.self"] doubleValue];
   CGFloat maxY = [[yValues valueForKeyPath:@"@max.self"] doubleValue];

   CGPoint origin = CGPointMake(minX, minY);
   CGPoint bottomRight = CGPointMake(maxX, maxY);

   NSArray *toReturn = [NSArray arrayWithObjects:
                        [NSValue valueWithCGPoint:origin],
                        [NSValue valueWithCGPoint:bottomRight],
                        nil];

   return toReturn;
}
</code>```

Body:
I'm looking for an algorithm to find bounding box (max/min points) of a closed quadratic bezier curve in Cartesian axis:

input: C (a closed bezier curve)
output: A B C D points

Image http://www.imagechicken.com/uploads/1270586513022388700.jpg

Note: above image shows a smooth curve. it could be not smooth. (have corners)

Body:
Timo-s first variant adapted to Objective-C

CGPoint CubicBezierPointAt(CGPoint p1, CGPoint p2, CGPoint p3, CGPoint p4, CGFloat t) {

   CGFloat x = CubicBezier(p1.x, p2.x, p3.x, p4.x, t);
   CGFloat y = CubicBezier(p1.y, p2.y, p3.y, p4.y, t);

   return CGPointMake(x, y);
}

// array containing TopLeft and BottomRight points for curve`s enclosing bounds
NSArray* CubicBezierExtremums(CGPoint p1, CGPoint p2, CGPoint p3, CGPoint p4) {

   CGFloat a, b, c, t, t1, t2, b2ac, sqrtb2ac;
   NSMutableArray *tValues = [NSMutableArray new];

   for (int i = 0; i < 2; i++) {
      if (i == 0) {
         a = 3 * (-p1.x + 3 * p2.x - 3 * p3.x + p4.x);
         b = 6 * (p1.x - 2 * p2.x +  p3.x);
         c = 3 * (p2.x - p1.x);
      }
      else {
         a = 3 * (-p1.y + 3 * p2.y - 3 * p3.y + p4.y);
         b = 6 * (p1.y - 2 * p2.y +  p3.y);
         c = 3 * (p2.y - p1.y);
      }

      if(ABS(a) < CGFLOAT_MIN) {// Numerical robustness
         if (ABS(b) < CGFLOAT_MIN) {// Numerical robustness
            continue;
         }

         t = -c / b;

         if (t > 0 && t < 1) {
            [tValues addObject:[NSNumber numberWithDouble:t]];
         }
         continue;
      }

      b2ac = pow(b, 2) - 4 * c * a;

      if (b2ac < 0) {
         continue;
      }

      sqrtb2ac = sqrt(b2ac);

      t1 = (-b + sqrtb2ac) / (2 * a);

      if (t1 > 0.0 && t1 < 1.0) {
         [tValues addObject:[NSNumber numberWithDouble:t1]];
      }

      t2 = (-b - sqrtb2ac) / (2 * a);

      if (t2 > 0.0 && t2 < 1.0) {
         [tValues addObject:[NSNumber numberWithDouble:t2]];
      }
   }

   int j = (int)tValues.count;

   CGFloat x = 0;
   CGFloat y = 0;
   NSMutableArray *xValues = [NSMutableArray new];
   NSMutableArray *yValues = [NSMutableArray new];

   while (j--) {
      t = [[tValues objectAtIndex:j] doubleValue];
      x = CubicBezier(p1.x, p2.x, p3.x, p4.x, t);
      y = CubicBezier(p1.y, p2.y, p3.y, p4.y, t);
      [xValues addObject:[NSNumber numberWithDouble:x]];
      [yValues addObject:[NSNumber numberWithDouble:y]];
   }

   [xValues addObject:[NSNumber numberWithDouble:p1.x]];
   [xValues addObject:[NSNumber numberWithDouble:p4.x]];
   [yValues addObject:[NSNumber numberWithDouble:p1.y]];
   [yValues addObject:[NSNumber numberWithDouble:p4.y]];

   //find minX, minY, maxX, maxY
   CGFloat minX = [[xValues valueForKeyPath:@"@min.self"] doubleValue];
   CGFloat minY = [[yValues valueForKeyPath:@"@min.self"] doubleValue];
   CGFloat maxX = [[xValues valueForKeyPath:@"@max.self"] doubleValue];
   CGFloat maxY = [[yValues valueForKeyPath:@"@max.self"] doubleValue];

   CGPoint origin = CGPointMake(minX, minY);
   CGPoint bottomRight = CGPointMake(maxX, maxY);

   NSArray *toReturn = [NSArray arrayWithObjects:
                        [NSValue valueWithCGPoint:origin],
                        [NSValue valueWithCGPoint:bottomRight],
                        nil];

   return toReturn;
}