Уведомления

Группа в Telegram: @pythonsu

Уведомления

  • Found 3495 posts.

Python для новичков » Гистограмма с отображением максимального значения » Апрель 24, 2021 14:57:08

Здравствуйте. подскажите пожалуйста, возможно ли сделать в pyqtgraph гистограмму с отображением максимального значения.
т.е у меня гистограмма показывает в реальном времени изменение 4-х переменных, они постоянно прыгаю и хотелось бы чтобы на графике отображался ее фиксированный максимальный пик ( в виде точки либо второго графика за основной диаграммой).


код отображения гистограммы
 # Plot widget for histogram
        self.pbar = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pbar.showGrid(x = True, y = True, alpha = 0.7)            
        self.pb1 = pg.BarGraphItem(x=np.linspace(1, 2, num=1), height=np.linspace(1, 2, num=1), width=0.3, pen = QtGui.QColor(153,0,0), brush=QtGui.QColor(153,0,0))
        self.pb2 = pg.BarGraphItem(x=np.linspace(2, 3, num=1), height=np.linspace(2, 3, num=1), width=0.3, pen=QtGui.QColor(229, 104, 19), brush=QtGui.QColor(229, 104, 19))
        self.pb3 = pg.BarGraphItem(x=np.linspace(3, 4, num=1), height=np.linspace(3, 4, num=1), width=0.3, pen=QtGui.QColor(221, 180, 10), brush=QtGui.QColor(221, 180, 10))
        self.pb4 = pg.BarGraphItem(x=np.linspace(4, 5, num=1), height=np.linspace(4, 5, num=1), width=0.3, pen=QtGui.QColor(30, 180, 30), brush=QtGui.QColor(30, 180, 30))
        self.pbar.addItem(self.pb1)  
        self.pbar.addItem(self.pb2)
        self.pbar.addItem(self.pb3)
        self.pbar.addItem(self.pb4)


 self.pb1.setOpts(height=self.DataMovingAverage[0][self.l-1])
                self.pb2.setOpts(height=self.DataMovingAverage[1][self.l-1])
                self.pb3.setOpts(height=self.DataMovingAverage[2][self.l-1])
                self.pb4.setOpts(height=self.DataMovingAverage[3][self.l-1])


основной код

 from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt 
import sys
import serial
import pyqtgraph as pg
import numpy as np
import time
from scipy.signal import butter, lfilter
import serial.tools.list_ports
from datetime import datetime
from scipy.fftpack import fft
# Main window
class GUI(QtWidgets.QMainWindow):
    # Initialize constructor
    def __init__(self):
          super(GUI, self).__init__()
          self.initUI()
    # Custom constructor
    def initUI(self): 
        # Values
        COM = '' #Example: COM='COM6'
        baudRate = 115200 #Serial frequency
        self.f = open(datetime.now().strftime("%Y_%m_%d_%H_%M_%S") + ".txt", "w")
        self.f.write(datetime.now().strftime("Date: %Y.%m.%d\rTime: %H:%M:%S") + "\r\n")
        self.f.write("File format: \r\nseconds | data1 | data2 | data3 | data4 | data5 | data6 | data7| data8 | data9 \r\n")
        self.l = 0 #Current point
        self.dt = 0.00125 #Updating time s
        self.fs = 1 / self.dt #Updating frequency in Hz
        self.passLowFrec = 10.0 #Low frequency for passband filter
        self.passHighFrec = 200.0 #Low frequency for passband filter
        self.dataWidth = 10000 #Maximum count of data points
        self.xH = [0]*10
        self.Time = [0]*self.dataWidth #Tine array
        self.timeWidth = 10 #Time width of plot
        self.Data = np.zeros((9, self.dataWidth))
        self.DataMovingAverage = np.zeros((4, self.dataWidth))
        self.MA = np.zeros((9, 3))
        self.MA_alpha = 0.95
        self.Y0 = np.zeros(9)
        self.X0 = np.zeros(9)
        self.FFT = 0
        self.msg_end = np.array([0])
        self.setWindowTitle("MYOstack GUI v1.0.1 | ELEMYO" + "    ( COM Port not found )")
        self.setWindowIcon(QtGui.QIcon('img/icon.png'))
        # Menu panel
        startAction = QtGui.QAction(QtGui.QIcon('img/start.png'), 'Start (Enter)', self)
        startAction.setShortcut('Return')
        startAction.triggered.connect(self.start)
        stopAction = QtGui.QAction(QtGui.QIcon('img/pause.png'), 'Stop (Space)', self)
        stopAction.setShortcut('Space')
        stopAction.triggered.connect(self.stop)
        refreshAction = QtGui.QAction(QtGui.QIcon('img/refresh.png'), 'Refresh (R)', self)
        refreshAction.setShortcut('r')
        refreshAction.triggered.connect(self.refresh)
        exitAction = QtGui.QAction(QtGui.QIcon('img/out.png'), 'Exit (Esc)', self)
        exitAction.setShortcut('Esc')
        exitAction.triggered.connect(self.close)
        # Toolbar
        toolbar = self.addToolBar('Tool')
        toolbar.addAction(startAction)
        toolbar.addAction(stopAction)
        toolbar.addAction(refreshAction)
        toolbar.addAction(exitAction)
        
        # Plot widget for 1st sensor
        self.pw1 = pg.PlotWidget(background = (21 , 21, 21, 255))
        self.pw1.showGrid(x = True, y = True, alpha = 0.7) 
        self.p1 = self.pw1.plot()
        self.p1.setPen(color=(100,255,255), width=1)
        # Plot widget for 2nd sensor
        self.pw2 = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pw2.showGrid(x = True, y = True, alpha = 0.7) 
        self.p2 = self.pw2.plot()
        self.p2.setPen(color=(100,255,255), width=1)
        # Plot widget for 3rd sensor
        self.pw3 = pg.PlotWidget(background = (21 , 21, 21, 255))
        self.pw3.showGrid(x = True, y = True, alpha = 0.7) 
        self.p3 = self.pw3.plot()
        self.p3.setPen(color=(100,255,255), width=1)
        # Plot widget for 4th sensor
        self.pw4 = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pw4.showGrid(x = True, y = True, alpha = 0.7) 
        self.p4 = self.pw4.plot()
        self.p4.setPen(color=(100,255,255), width=1)
        # Plot widget for 5th sensor
        self.pw5 = pg.PlotWidget(background = (21 , 21, 21, 255))
        self.pw5.showGrid(x = True, y = True, alpha = 0.7) 
        self.p5 = self.pw5.plot()
        self.p5.setPen(color=(100,255,255), width=1)
        # Plot widget for 6th sensor
        self.pw6 = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pw6.showGrid(x = True, y = True, alpha = 0.7) 
        self.p6 = self.pw6.plot()
        self.p6.setPen(color=(100,255,255), width=1)
        # Plot widget for 7th sensor
        self.pw7 = pg.PlotWidget(background = (21 , 21, 21, 255))
        self.pw7.showGrid(x = True, y = True, alpha = 0.7) 
        self.p7 = self.pw7.plot()
        self.p7.setPen(color=(100,255,255), width=1)
        # Plot widget for 8th sensor
        self.pw8 = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pw8.showGrid(x = True, y = True, alpha = 0.7) 
        self.p8 = self.pw8.plot()
        self.p8.setPen(color=(100,255,255), width=1)
        # Plot widget for 9th sensor
        self.pw9 = pg.PlotWidget(background = (21 , 21, 21, 255))
        self.pw9.showGrid(x = True, y = True, alpha = 0.7) 
        self.p9 = self.pw9.plot()
        self.p9.setPen(color=(100,255,255), width=1)
        
        # Plot widget for spectral Plot
        self.pw10 = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pw10.showGrid(x = True, y = True, alpha = 0.7) 
        self.p10 = self.pw10.plot()
        self.p10.setPen(color=(100,255,255), width=1)
        self.pw10.setLabel('bottom', 'Frequency', 'Hz')
        
        # Plot widget for histogram
        self.pbar = pg.PlotWidget(background = (13 , 13, 13, 255))
        self.pbar.showGrid(x = True, y = True, alpha = 0.7)            
        self.pb1 = pg.BarGraphItem(x=np.linspace(1, 2, num=1), height=np.linspace(1, 2, num=1), width=0.3, pen = QtGui.QColor(153,0,0), brush=QtGui.QColor(153,0,0))
        self.pb2 = pg.BarGraphItem(x=np.linspace(2, 3, num=1), height=np.linspace(2, 3, num=1), width=0.3, pen=QtGui.QColor(229, 104, 19), brush=QtGui.QColor(229, 104, 19))
        self.pb3 = pg.BarGraphItem(x=np.linspace(3, 4, num=1), height=np.linspace(3, 4, num=1), width=0.3, pen=QtGui.QColor(221, 180, 10), brush=QtGui.QColor(221, 180, 10))
        self.pb4 = pg.BarGraphItem(x=np.linspace(4, 5, num=1), height=np.linspace(4, 5, num=1), width=0.3, pen=QtGui.QColor(30, 180, 30), brush=QtGui.QColor(30, 180, 30))
        self.pbar.addItem(self.pb1)  
        self.pbar.addItem(self.pb2)
        self.pbar.addItem(self.pb3)
        self.pbar.addItem(self.pb4)
        
        self.pbar.setLabel('bottom', 'Sensor number')
        
        # Styles
        centralStyle = "color: rgb(255, 255, 255); background-color: rgb(13, 13, 13);"
        editStyle = "border-style: solid; border-width: 1px;"
        
        # Settings zone
        filtersText = QtWidgets.QLabel("FILTERS:")
        self.passLowFreq = QtWidgets.QLineEdit(str(self.passLowFrec), self)
        self.passLowFreq.setMaximumWidth(100)
        self.passLowFreq.setStyleSheet(editStyle)
        self.passHighFreq = QtWidgets.QLineEdit(str(self.passHighFrec), self)
        self.passHighFreq.setMaximumWidth(100)
        self.passHighFreq.setStyleSheet(editStyle)
        self.bandpass = QtWidgets.QCheckBox("BANDPASS FILTER:")
        self.bandstop50 = QtWidgets.QCheckBox("NOTCH 50 Hz")
        self.bandstop60 = QtWidgets.QCheckBox("NOTCH 60 Hz")
        self.MovingAverage = QtWidgets.QCheckBox("Signal envelope")
        
        fft1 = QtWidgets.QRadioButton('1')
        fft1.setChecked(True)
        fft1.Value = 1
        fft2 = QtWidgets.QRadioButton('2')
        fft2.Value = 2
        fft3 = QtWidgets.QRadioButton('3')
        fft3.Value = 3
        fft4 = QtWidgets.QRadioButton('4')
        fft4.Value = 4
        fft5 = QtWidgets.QRadioButton('5')
        fft5.Value = 5
        fft6 = QtWidgets.QRadioButton('6')
        fft6.Value = 6
        fft7 = QtWidgets.QRadioButton('7')
        fft7.Value = 7
        fft8 = QtWidgets.QRadioButton('8')
        fft8.Value = 8
        fft9 = QtWidgets.QRadioButton('9')
        fft9.Value = 9
        self.button_group = QtWidgets.QButtonGroup()
        
        
        self.button_group.buttonClicked.connect(self._on_radio_button_clicked)
        
        self.l11 = QtWidgets.QLabel("")
        self.l11.setStyleSheet("font-size: 25px; background-color: rgb(21,21,21);")
        self.l13 = QtWidgets.QLabel("")
        self.l13.setStyleSheet("font-size: 25px; background-color: rgb(21,21,21);")
        self.l15 = QtWidgets.QLabel("")
        self.l15.setStyleSheet("font-size: 25px; background-color: rgb(21,21,21);")
        self.l17 = QtWidgets.QLabel("")
        self.l17.setStyleSheet("font-size: 25px; background-color: rgb(21,21,21);")
        self.l19 = QtWidgets.QLabel("")
        self.l19.setStyleSheet("font-size: 25px; background-color: rgb(21,21,21);")
        self.l1 = QtWidgets.QLabel(" 1 ")
        self.l1.setStyleSheet("font-size: 25px; background-color: rgb(153,0,0); border-radius: 14px;")
        self.l2 = QtWidgets.QLabel(" 2")
        self.l2.setStyleSheet("font-size: 25px; background-color: rgb(229, 104, 19); border-radius: 14px;") 
        self.l3 = QtWidgets.QLabel(" 3 ")
        self.l3.setStyleSheet("font-size: 25px; background-color: rgb(221, 180, 10); border-radius: 14px;")
        self.l4 = QtWidgets.QLabel(" 4 ")
        self.l4.setStyleSheet("font-size: 25px; background-color: rgb(30, 180, 30); border-radius: 14px;")
        self.l5 = QtWidgets.QLabel(" 5 ")
        self.l5.setStyleSheet("font-size: 25px; background-color: rgb(11, 50, 51); border-radius: 14px;")
        self.l6 = QtWidgets.QLabel(" 6 ")
        self.l6.setStyleSheet("font-size: 25px; background-color: rgb(29, 160, 191); border-radius: 14px;")
        self.l7 = QtWidgets.QLabel(" 7 ")
        self.l7.setStyleSheet("font-size: 25px; background-color: rgb(30, 30, 188); border-radius: 14px;")
        self.l8 = QtWidgets.QLabel(" 8 ")
        self.l8.setStyleSheet("font-size: 25px; background-color: rgb(75, 13, 98); border-radius: 14px;")
        self.l9 = QtWidgets.QLabel(" 9 ")
        self.l9.setStyleSheet("font-size: 25px; background-color: rgb(139, 0, 55); border-radius: 14px;")
        # Main widget
        centralWidget = QtWidgets.QWidget()
        centralWidget.setStyleSheet(centralStyle)
        # Layout
        vbox = QtWidgets.QVBoxLayout()
        
        layout = QtWidgets.QGridLayout()
        
        layout.addWidget(self.l1, 0, 1, Qt.AlignVCenter)
        layout.addWidget(self.l2, 0, 4, Qt.AlignVCenter)
        
        layout.addWidget(self.l3, 1, 1, Qt.AlignVCenter)
        layout.addWidget(self.l4, 1, 4, Qt.AlignVCenter)
        
        
        
        
        layout.addWidget(self.pw1, 0, 2)
        layout.addWidget(self.pw2, 0, 3)
        layout.addWidget(self.pw3, 1, 2)
        layout.addWidget(self.pw4, 1, 3)
        
        layout.addWidget(self.pbar, 2, 2)
        
        
        
       
            
        
        vbox.addWidget(self.bandpass) 
          
        
        vbox.addLayout(layout)
        centralWidget.setLayout(vbox)
        self.setCentralWidget(centralWidget)  
        self.showMaximized()
        self.show()
        # Serial monitor
        self.monitor = SerialMonitor(COM, baudRate)
        self.monitor.bufferUpdated.connect(self.updateListening, QtCore.Qt.QueuedConnection)
    # Start working
    def start(self):
        self.monitor.running = True
        self.monitor.start()
    # Pause
    def stop(self):
        self.monitor.running = False    
    # Refresh
    def refresh(self):
        self.l = 0 #Current point
        self.Time = [0]*self.dataWidth #Tine array
        self.Data = np.zeros((9, self.dataWidth))
        self.DataMovingAverage = np.zeros((9, self.dataWidth))
        self.Time = [0]*self.dataWidth
        self.msg_end = 0        
    # Update
    def updateListening(self, msg):
        # Update variables
        self.setWindowTitle("MYOstack GUI v1.0.1 | ELEMYO " + 
                            "    ( " + self.monitor.COM + " , " + str(self.monitor.baudRate) + " baud )")
        s = self.passLowFreq.text()
        if s.isdigit():
            self.passLowFrec = float(s)
        s = self.passHighFreq.text()
        if s.isdigit():
            self.passHighFrec = float(self.passHighFreq.text())
        # Parsing data from serial buffer
        msg = msg.decode(errors='ignore')
        if len(msg) >= 2:
            msg_end_n = msg.rfind("\r", 1)
            msg_begin = self.msg_end
            self.msg_end = msg[msg_end_n:len(msg)]
            if(self.l > 2):
                msg = msg_begin + msg[0:msg_end_n]
            for st in msg.split('\r\n'):
                s = st.split(' ')
                if (len(s) == 4) :
                    if ( self.l == self.dataWidth):
                        self.l = 0
                    for i in range(4):
                        self.Data[i][self.l] = int(s[i])/1.024*3.3
                        self.DataMovingAverage[i][self.l] = self.movingAverage(i, self.Data[i][self.l], self.MA_alpha)
                        
                    self.Time[self.l] = self.Time[self.l - 1] + self.dt
                    self.f.write(str(round(self.Time[self.l], 3)) + " " + str(self.Data[0][self.l]) + " " + str(self.Data[1][self.l]) + " "
                                 + str(self.Data[2][self.l]) + " " + str(self.Data[3][self.l]) + " "
                                 + str(self.Data[4][self.l]) + "\r\n")
                    
                    self.l = self.l + 1
                
        # Filtering
        Data = np.zeros((9, self.dataWidth))
        for i in range(9):
            Data[i] = np.concatenate((self.Data[i][self.l: self.dataWidth], self.Data[i][0: self.l]))
        
        Time = self.Time[self.l + 1: self.dataWidth-1]+(self.Time[0: self.l])
        
        if (self.bandpass.isChecked() == 1 and self.passLowFrec < self.passHighFrec 
            and self.passLowFrec > 0 and self.fs > 2*self.passHighFrec):
            for i in range(9):
                Data[i] = self.butter_bandpass_filter(Data[i], self.passLowFrec, self.passHighFrec, self.fs)
        if self.bandstop50.isChecked() == 1:
            if self.fs > 110: 
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 48, 52, self.fs)
            if self.fs > 210: 
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 98, 102, self.fs)
            if self.fs > 310: 
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 148, 152, self.fs)
            if self.fs > 410:
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 198, 202, self.fs)
        if self.bandstop60.isChecked() == 1:
            if self.fs > 130:
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 58, 62, self.fs)
            if self.fs > 230:
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 118, 122, self.fs)
            if self.fs > 330:
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 158, 162, self.fs)
            if self.fs > 430:
                for i in range(9): Data[i] = self.butter_bandstop_filter(Data[i], 218, 222, self.fs)
        # Shift the boundaries of the graph
        timeCount = self.Time[self.l - 1] // self.timeWidth
        # Update plot
        if (self.l > 3):
            # Main signal graphic
            self.pw1.setXRange(self.timeWidth * timeCount, self.timeWidth * ( timeCount + 1))
            self.pw2.setXRange(self.timeWidth * timeCount, self.timeWidth * ( timeCount + 1))
            self.pw3.setXRange(self.timeWidth * timeCount, self.timeWidth * ( timeCount + 1))
            self.pw4.setXRange(self.timeWidth * timeCount, self.timeWidth * ( timeCount + 1))
            self.pw5.setXRange(self.timeWidth * timeCount, self.timeWidth * ( timeCount + 1))
            
            
            if self.MovingAverage.isChecked() == 1:
                for i in range(9):
                    Data[i] = np.concatenate((self.DataMovingAverage[i][self.l: self.dataWidth], self.DataMovingAverage[i][0: self.l]))
            
            self.p1.setData(y=Data[0][0: self.dataWidth-2], x = Time[0: self.dataWidth-1])
            self.p2.setData(y=Data[1][0: self.dataWidth-2], x = Time[0: self.dataWidth-1])
            self.p3.setData(y=Data[2][0: self.dataWidth-2], x = Time[0: self.dataWidth-1])
            self.p4.setData(y=Data[3][0: self.dataWidth-2], x = Time[0: self.dataWidth-1])
            
            if (self.l > 100):
                self.pb1.setOpts(height=self.DataMovingAverage[0][self.l-1])
                self.pb2.setOpts(height=self.DataMovingAverage[1][self.l-1])
                self.pb3.setOpts(height=self.DataMovingAverage[2][self.l-1])
                self.pb4.setOpts(height=self.DataMovingAverage[3][self.l-1])
               
            
            
            # FFT graphic
            if self.l > 1000:
                Y = abs(fft(self.Data[self.button_group.checkedId()-1][self.l-1000: self.l-2])) / 998
                X = 1/self.dt*np.linspace(0, 1, 998)
                self.FFT = (1-0.85)*Y + 0.85*self.FFT
                self.p10.setData(y=self.FFT[2: int(len(self.FFT)/2)], x=X[2:int(len(X)/2)]) 
                    
    # Values for butterworth bandpass filter
    def butter_bandpass(self, lowcut, highcut, fs, order = 4):
        nyq = 0.5 * fs
        low = lowcut / nyq
        high = highcut / nyq
        b, a = butter(order, [low, high], btype = 'bandpass')
        return b, a
    # Butterworth bandpass filter
    def butter_bandpass_filter(self, data, lowcut, highcut, fs, order = 4):
        b, a = self.butter_bandpass(lowcut, highcut, fs, order=order)
        y = lfilter(b, a, data)
        return y
    # Values for butterworth bandstop filter
    def butter_bandstop(self, lowcut, highcut, fs, order = 2):
        nyq = 0.5 * fs
        low = lowcut / nyq
        high = highcut / nyq
        b, a = butter(order, [low, high], btype = 'bandstop')
        return b, a
    # Butterworth bandstop filter
    def butter_bandstop_filter(self, data, lowcut, highcut, fs, order = 4):
        b, a = self.butter_bandstop(lowcut, highcut, fs, order = order)
        y = lfilter(b, a, data)
        return y
    def movingAverage(self, i, data, alpha):
        wa = 2.0*self.fs*np.tan(3.1416*1/self.fs)
        HPF = (2*self.fs*(data - self.X0[i]) - (wa-2*self.fs)*self.Y0[i])/(2*self.fs+wa)
        self.Y0[i] = HPF
        self.X0[i] = data
        data = HPF
        if data < 0:
            data = -data
        self.MA[i][0] = (1 - alpha)*data + alpha*self.MA[i][0];
        self.MA[i][1] = (1 - alpha)*(self.MA[i][0]) + alpha*self.MA[i][1];
        self.MA[i][2] = (1 - alpha)*(self.MA[i][1]) + alpha*self.MA[i][2];
        return self.MA[i][2]*4
    # Change gain
    def _on_radio_button_clicked(self, button):
        if self.monitor.COM != '':
            self.monitor.ser.write(bytearray([button.Value]))
    # Exit event
    def closeEvent(self, event):
        self.f.close()
        self.monitor.ser.close()
        event.accept()
# Serial monitor class
class SerialMonitor(QtCore.QThread):
    bufferUpdated = QtCore.pyqtSignal(bytes)
    # Custom constructor
    def __init__(self, COM, baudRate):
        QtCore.QThread.__init__(self)
        self.running = False
        self.filter = False
        self.COM = COM
        self.baudRate = baudRate
        self.baudRate = baudRate
        self.checkPort = 1
    # Listening port
    def run(self):
        while self.running is True:
            while self.COM == '': 
                ports = serial.tools.list_ports.comports(include_links=False)
                for port in ports :
                    self.COM = port.device
                if self.COM != '':
                    time.sleep(0.5)
                    self.ser = serial.Serial(self.COM, self.baudRate)
                    self.checkPort = 0
            while self.checkPort:
                ports = serial.tools.list_ports.comports(include_links=False)
                for port in ports :
                    if self.COM == port.device:
                        time.sleep(0.5)
                        self.ser = serial.Serial(self.COM, self.baudRate)
                        self.checkPort = 0
                   
            # Waiting for data
            while (self.ser.inWaiting() == 0):
                pass
            # Reading data
            msg = self.ser.read( self.ser.inWaiting() )
            if msg:
                #Parsing data
                self.bufferUpdated.emit(msg)
                time.sleep(0.1)
                
# Starting program       
if __name__ == '__main__':
    app = QtCore.QCoreApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)
    window = GUI()
    window.show()
    window.start()
    sys.exit(app.exec_())

Python для новичков » Игра на питоне. Ошибка, питон не видит спрайты » Апрель 23, 2021 20:16:57

Всем привет. Столкнулся с такой проблемой при освоении PyGame. На этапе загрузки в мою импровизированную игру спрайтов, мне выдаёт ошибку(Подробнее на скриншоте). Код перепроверял миллион раз. Но всё равно файл с кодом не видит файлы спрайтов. Для полноты картины скину скриншот папки. Прошу помочь.

walkRight =

walkLeft =

walkUp =

walkDown =

Python для новичков » Округление в money формат » Апрель 23, 2021 15:44:05

python 2.7
Имеем число Decimal с некоторым числом знаков после запятой. Задача округлить в формат денежной единицы в ближнюю часть

 from decimal import Decimal, ROUND_HALF_UP
print Decimal(Decimal(str(1.1247)).quantize(Decimal('.001'), rounding=ROUND_HALF_UP))
>>>1.125 # правильно при округлении до трех знаков
 print Decimal(Decimal(str(1.1247)).quantize(Decimal('.01'), rounding=ROUND_HALF_UP))
>>>1.12 # не правильно при округлении до двух знаков. Ожидается 1.13
print Decimal(Decimal(str(1.124)).quantize(Decimal('.01'), rounding=ROUND_HALF_UP))
>>>1.12 # правильно при округлении до двух знаков
print Decimal(Decimal(str(1.125)).quantize(Decimal('.01'), rounding=ROUND_HALF_UP))
>>>1.13 # правильно при округлении до двух знаков

Т.е. округляет правильно при уменьшении на 1 знак после запятой. А когда знаков больше, то они не учитываются в расчете. А это не верно.

Как заставить правильно округлять 1.1247 в 1.13 ?

Python для новичков » Помогите » Апрель 21, 2021 19:04:50

Помогите пожалуйста 5 любых заданий с циклами и оператором def

Python для экспертов » Помогите решить несложную задачу, пожалуйста! » Апрель 20, 2021 19:14:16

Задача:
Есть код программы, который выводит смену смену пикета-как показано в таблице, но он работает для значения до 1000.
Необходимо дополнить программу которая будет еще показывать строку:1016 900 ->ПК10.Конечный вывод должен быть таким:

1016 900 ->ПК10
900 899 -> ПК9
800 799 -> ПК8
700 699 -> ПК7
600 599 -> ПК6
500 499 -> ПК5
400 399 -> ПК4
300 299 -> ПК3
200 199 -> ПК2
100 99 -> ПК1

Код программы:

def is_new_pk(prev_m, this_m):
if prev_m == this_m:
return 0
prev_m = prev_m % 100
this_m = this_m % 100
if prev_m == 99 and this_m == 0:
return +1
if prev_m == 0 and this_m == 99: # предыдущий=0,следующий = 99
# Смена пикета по убыванию (100->99)
return -1

pm = None
p = 0

for m in range(1016, 1, -1):# (1, 1016):
if pm is not None:
pk = is_new_pk(pm, m)
if pk: # pk=+1 -1 .
if pk > 0: # pk=+1
pk_n = 1 + pm // 100 # определение пикета
else:
pk_n = 1 + m // 100 # определение пикета .
print(“%d %d -> ПК%d” % (pm, m, pk_n))
p = 0
else:
p += 1
pm = m

Помогите пожалуйста, буду очень признателен!

Базы данных » $ Нужна помощь, подзапрос для ORDER BY / SqlAlchemy » Апрель 20, 2021 16:58:06

нужна помощь в построении подзапроса для ORDER BY через SqlAlchemy.
(внизу прикреплен скрин таблиц)


Логика:
1). Есть таблица со списком девайсов (“UECAP_DEVICE”)

2). Девайсы тестируются в лаборатории в трёх условиях:
- с фильтром (condition = “filter”)
- без фильтра (condition = “n_filter”)
- 5G условия (condition = “5g”)
Вторая таблица - это “UECAP_DEVICE_CONDITION”, имеет поля:
▸ device_id (ссылка (FK) на девайс из таблицы “UECAP_DEVICE”)
▸ binary_id (ссылка (FK) на HEX-код из таблицы “UECAP_BINARY”, который является результатом тестирования оборудования)
▸ uecap_analyze_id (ссылка (FK) на запись из таблицы “UECAP_ ANALYZE”, которая хранит результаты декодирования HEX-кода (характеристики девайса))
▸ condition (имеет одно из значений: “filter”, “n_filter”, “5g” и “combined”).
Сondition = “combined”, это условное состояние, которое просто нужно для хранения объединённых данных из вышеуказанных трех условий (“filter”, “n_filter”, “5g”), которые хранятся в таблице “UECAP_ ANALYZE”. И поэтому у “combined” нет ссылки на таблицу “UECAP_BINARY” (т. к. он не имеет HEX-кода).

3). И третья таблица — это “UECAP_ ANALYZE”.
Для “filter”, “n_filter” и “5g” — там хранятся результаты декодирования HEX-кода (характеристики девайса).
Для “combined” — там хранятся merged/агрегированные данные из трёх вышеуказанных состояний.


QUERY
По умолчанию отправляется запрос в БД, который включает данные из таблиц:
“UECAP_DEVICE” + “UECAP_DEVICE_CONDITION” (WHERE condition = “combined”) + UECAP_ ANALYZE (привязанная через FK к uecap_device_condition.condition = “combined”)
И они отсортированы по ID девайса.
Таким образом появляется список девайсов с merged информацией (для состояния “combined”).


Но мне нужно отсортировать список девайсов по двум вариантам:
1). длина (length) HEX-кода (таблица “UECAP_BINARY”, поле “UECAP_BIN”) из состояния condition = “5g”.

2). получаить максимальное значение длины HEX-кода для всех трёх состояний (“filter”, “n_filter”, “5g”) и уже по нему отсортировать список девайсов.
Например для некоторого девайса:
length(uecap_binary.uecap_bin) для “filter” = 100
length(uecap_binary.uecap_bin) для “n_filter” = 200
length(uecap_binary.uecap_bin) для “5g” = 300
Соответственно в сортировке девайсов будет учавствовать значение 300.

Центр помощи » $ Нужна помощь, подзапрос для ORDER BY / SqlAlchemy » Апрель 20, 2021 16:57:11

нужна помощь в построении подзапроса для ORDER BY через SqlAlchemy.
(внизу прикреплен скрин таблиц)


Логика:
1). Есть таблица со списком девайсов (“UECAP_DEVICE”)

2). Девайсы тестируются в лаборатории в трёх условиях:
- с фильтром (condition = “filter”)
- без фильтра (condition = “n_filter”)
- 5G условия (condition = “5g”)
Вторая таблица - это “UECAP_DEVICE_CONDITION”, имеет поля:
▸ device_id (ссылка (FK) на девайс из таблицы “UECAP_DEVICE”)
▸ binary_id (ссылка (FK) на HEX-код из таблицы “UECAP_BINARY”, который является результатом тестирования оборудования)
▸ uecap_analyze_id (ссылка (FK) на запись из таблицы “UECAP_ ANALYZE”, которая хранит результаты декодирования HEX-кода (характеристики девайса))
▸ condition (имеет одно из значений: “filter”, “n_filter”, “5g” и “combined”).
Сondition = “combined”, это условное состояние, которое просто нужно для хранения объединённых данных из вышеуказанных трех условий (“filter”, “n_filter”, “5g”), которые хранятся в таблице “UECAP_ ANALYZE”. И поэтому у “combined” нет ссылки на таблицу “UECAP_BINARY” (т. к. он не имеет HEX-кода).

3). И третья таблица — это “UECAP_ ANALYZE”.
Для “filter”, “n_filter” и “5g” — там хранятся результаты декодирования HEX-кода (характеристики девайса).
Для “combined” — там хранятся merged/агрегированные данные из трёх вышеуказанных состояний.


QUERY
По умолчанию отправляется запрос в БД, который включает данные из таблиц:
“UECAP_DEVICE” + “UECAP_DEVICE_CONDITION” (WHERE condition = “combined”) + UECAP_ ANALYZE (привязанная через FK к uecap_device_condition.condition = “combined”)
И они отсортированы по ID девайса.
Таким образом появляется список девайсов с merged информацией (для состояния “combined”).


Но мне нужно отсортировать список девайсов по двум вариантам:
1). длина (length) HEX-кода (таблица “UECAP_BINARY”, поле “UECAP_BIN”) из состояния condition = “5g”.

2). получаить максимальное значение длины HEX-кода для всех трёх состояний (“filter”, “n_filter”, “5g”) и уже по нему отсортировать список девайсов.
Например для некоторого девайса:
length(uecap_binary.uecap_bin) для “filter” = 100
length(uecap_binary.uecap_bin) для “n_filter” = 200
length(uecap_binary.uecap_bin) для “5g” = 300
Соответственно в сортировке девайсов будет учавствовать значение 300.

Python для новичков » Процедура вывода на экран запись числа, меньшего, чем 8^10, в виде 10 знаков в восьмеричной системе счисления. » Апрель 19, 2021 16:53:24

Напишите процедуру, которая выводит на экран запись числа, меньшего, чем 8^10, в виде 10 знаков в восьмеричной системе счисления.

Python для новичков » Создание из geojson img » Апрель 18, 2021 16:16:25

Всем привет. Пытаюсь найти оптимальное решение своей задачи:
Есть куча объектов geojson, из них у меня строится таблица с координатами.
Хотелось бы еще добавить превью объекта (полигона) в конце таблицы.
Подскажите, чем лучше сделать отрисовку?
Отдельно брать координаты и рисовать(если да, то чем?), или есть вариант сразу из geojson в jpg, допустим.

Python для новичков » не запускается майнер на манжаро nuxhashd python3.9/site-packages/nuxhash/daemon.py » Апрель 16, 2021 06:17:56

nuxhashd
 Traceback (most recent call last):
  File "/usr/bin/nuxhashd", line 33, in <module>
    sys.exit(load_entry_point('nuxhash==1.0.0b2', 'console_scripts', 'nuxhashd')())
  File "/usr/lib/python3.9/site-packages/nuxhash/__init__.py", line 3, in nuxhashd
    main()
  File "/usr/lib/python3.9/site-packages/nuxhash/daemon.py", line 103, in main
    nx_benchmarks = run_missing_benchmarks(
  File "/usr/lib/python3.9/site-packages/nuxhash/daemon.py", line 155, in run_missing_benchmarks
    miner.load()
  File "/usr/lib/python3.9/site-packages/nuxhash/miners/excavator.py", line 378, in load
    self.server.start()
  File "/usr/lib/python3.9/site-packages/nuxhash/miners/excavator.py", line 124, in start
    raise miner.MinerStartFailed
nuxhash.miners.miner.MinerStartFailed
2021-04-16 13:46:09,086 CRITICAL: Crash! Killing all miners.

версия gui
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
self.run()
File "/usr/lib/python3.9/threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.9/site-packages/nuxhash/gui/mining.py", line 140, in do_requests
wallet, unpaid = get_balances(self._Settings)
File "/usr/lib/python3.9/site-packages/nuxhash/nicehash.py", line 26, in get_balances
response = nh.public_api(HOST).request(
File "/usr/lib/python3.9/site-packages/nuxhash/nhrest/python/nicehash.py", line 38, in request
raise Exception(str(response.status_code) + ": " + response.reason)
Exception: 404: Not Found

Python для новичков » Создания HUD`a для игры Phasmafobia » Апрель 15, 2021 22:19:35

Доброго, форумчане. Учу питон по курсам на степике, уже прошёл ООП (Egoroff_channel). Но чего то полезного я всё ещё не написал. Почитал, вроде как, если нету соуса то надо делать SQL инъекцию, и через SQL запросы брать данные которые мне нужны(хочу выводить имя призрака и статус заданий).
СУТЬ: я вообще в правильном направлении? Что мне нужно гуглить чтобы добиться желаемого?

Центр помощи » Реализация алгоритмов поиска  » Апрель 15, 2021 11:34:33


1 (permalink)
Реализация алгоритмов поиска
Сегодня, 11:27. Просмотров 0. Ответов 0
Метки Укажите метки (Редактировать метки, Все метки)
1. Реализовать класс генерирующий строку состоящую из 20-30 произвольных символов ; методы класса :
-генерирующий исходную строку T
-генерирующий искомую строку S
- поиска
2. Произвести поиск строки S в строке T (вывести на экран начальную позицию совпадения) методами:
A) ПРЯМОГО ПОИСКА
B) КНУТА МОРИСА ПРАТТА
C) БОУЕРА МУРА

Базы данных » Группировка и агрегация по списку полей » Апрель 15, 2021 09:38:55

1 (permalink)
Группировка и агрегация по списку полей
12.04.2021, 10:41. Просмотров 177. Ответов 0
Метки Укажите метки (Редактировать метки, Все метки)
Добрый день!
Имеется набор данных c двумя категориями показателей:
name | показатель 1.1 | показатель 1.2 | показатель 1.3 | показатель 2.1 | показатель 2.2 | показатель 2.3|


Требуется сгруппировать данные по одному из полей и получить сумму по категориям показателей с агрегацией по сумме.
Т.е должно получиться вот так
name | сумма показатель1 | Сумма показатель 2 |
Вася |
Саша |

Я формирую поля в списки (в реальности показателей внутри каждой категории более 10 шт)


 lst_pok1=[' показатель 1.1', ' показатель 1.2', ' показатель 1.3']
lst_pok2=[' показатель 2.1', ' показатель 2.2', ' показатель 2.3']
затем делаю так:


 df_res=df_pok.groupby(['name']) [lst_pok1].agg(['sum'])
df_res=df_res[lst_pok1].sum(axis='columns')


С одним списков все ОК, но как добавить в выражение следующий список полей?
Пробую через словарь


 df_res=df_pok.groupby(['name]).agg({' lst_pok1':'sum'})
df_res=df_res[lst_pok1].sum(axis='columns')


Выдает ошибку, даже с одним списком.
Возможно все это бред, но я только взялся за pandа, не судите строго…

Python для новичков » Графы » Апрель 11, 2021 21:15:28

Нужно написать функцию:На вход принимает матрицу весов W графа (список списков). На выходе матрица смежности А графа без учета весов ребер (список списков).
Использовать сгенерированный граф
Вот генератор графов:
 import random
import pprint
def graph_generator(n, mean_degree, max_weight):
    if mean_degree < 2 * (n - 1) / n:
        mean_degree = 2 * (n - 1) / n
    if mean_degree > n - 1:
        mean_degree = (n - 1)
    num_of_edges = int(mean_degree * n / 2)
    W = []
    for i in range(n):
        W.append(['-'] * n)
        W[i][i] = 0
    stack = []
    for i in range(n):
        stack.append(i)
    random.shuffle(stack)
    while stack:
        first = stack.pop()
        if stack:
            second = random.choice(stack)
            W[first][second] = W[second][first] = random.randint(1, max_weight)
    edges_not_tree = num_of_edges - (n - 1)
    for _ in range(edges_not_tree):
        first = random.randint(0, n - 1)
        second = random.randint(0, n - 1)
    W[first][second] = W[second][first] = random.randint(1, max_weight)
    return W

Python для новичков » чтение из неблокирующего сокета » Апрель 6, 2021 16:27:55

всем привет
пытаюсь читать из сокета. иногда сервер перезапускается и это отслеживаю отправкой сообщения в сокет (отправка своего рода пинга, в ответ получаю понг). перезапускаю реконнект к сокету но данные уже не читаются. что не так?
 host = '192.168.100.45'
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#clientSocket.setblocking(0)
#clientSocket.settimeout(2)
#fcntl.fcntl(clientSocket, fcntl.F_SETFL, os.O_NONBLOCK)
#clientSocket.connect( ( host, 8902 ) )
#-------------------------------------------------------------------------------------------------------------------------------
class pingTimer():
   def __init__(self,t,hFunction):
      self.t=t
      self.hFunction = hFunction
      self.thread = Timer(self.t,self.handle_function)
   def handle_function(self):
      self.hFunction()
      self.thread = Timer(self.t,self.handle_function)
      self.thread.start()
   def start(self):
      self.thread.start()
   def cancel(self):
      self.thread.cancel()
#-------------------------------------------------------------------------------------------------------------------------------
def send_ping():
#    global clientSocket
    print ("send ping")
    try:
        clientSocket.send(b'33333{"cmd":"ping","rid":"RID000000"}')
    except:
      print("error send ping, socket close")
      clientSocket.close()
      connect()      
#    timer.start()    
#-------------------------------------------------------------------------------------------------------------------------------	
def connect():
    global clientSocket
    try:
        print( "try to connected to device" )
        clientSocket.connect( ( host, 8902 ) )
        clientSocket.listen(1)
#        fcntl.fcntl(clientSocket, fcntl.F_SETFL, os.O_NONBLOCK)
        connected = True
        print ("connected")
    except socket.error:
        connected = False  
        clientSocket = socket.socket()
        print( "connection lost... reconnecting" )
        while not connected:
            try:
                clientSocket.connect( ( host, 8902 ) )  
                connected = True  
                print( "re-connection successful" )
            except socket.error:  
                sleep(2)
                print("try to reconnect.....")
#-------------------------------------------------------------------------------------------------------------------------------
def recv_msg():
    global clientSocket
    while True:
        recv_msg = clientSocket.recv(1024)
        if not recv_msg:
            sys.exit(0)
        recv_msg = recv_msg.decode()
        print('message recive')
        print(recv_msg)
#-------------------------------------------------------------------------------------------------------------------------------
# main start
#connect()
t_ping = pingTimer(5,send_ping)
t_ping.start()
#t_listen = threading.Thread(target = recv_msg)
connect()
#t_listen.start()
while True:
    recv_msg()
#    print("while1")
#     print ('recv')

Центр помощи » Помогите с написанием программы, пожалуйста » Апрель 5, 2021 17:55:20

Нужно написать таймер для интервальных тренировок на Python, именно приложение для Windows, помогите пожалуйста я пень, в питоне вообще не разбираюсь тк не проходили его, дали проект за два месяца до конца обучения, а еще к ЕГЭ готовиться когда то надо успевать

Вот пример входных данных в программу:
6wk Beginner FTP Builder
Weeks: 6 (Кол-во недель в тренировке)

WEEK 1(первая неделя)
Day 1 - Foundation(первый день)
10min(время первого цикла тренировки) from 50 to 55%(нагрузка) FTP
4min @ 73% FTP
2min @ 52% FTP
4min @ 73% FTP
2min @ 52% FTP
4min @ 73% FTP
2min @ 52% FTP
4min @ 73% FTP
2min @ 52% FTP
4min @ 73% FTP
2min @ 52% FTP
10min from 55 to 50% FTP

И так для каждого дня каждой недели

Network » Сервер отправляет всем клиентам (Даже отправителю) то что написал отправитель. Как исправить? » Апрель 5, 2021 17:51:59

Я делаю мессенджер на питоне, и столкнулся вот с такой проблемой: из клиента передается на сервер передается сообщение data, в котором указано время отправки, ник отправляющего и сам текст.
Эту переменную data сервер кидает всем клиентам, которые ее уже читают.
Так вот, проблема в том что, клиент, печатая все в инпут, оставляет у сабя то, что, он напечатал, и отправляет серверу, которы как было сказанно ранее, рассылает сообщение прям всем клиентам, в том числе и отправляющему. То есть получается как-то так:

Привет) # текст инпута
Джони228>Привет) #то что прислал всем клиентам сервак

АлахАкбр>Да, кстати, как тебе чашечка кота?)

Такой мягкий и немного жидкий кот) # текст инпута
Джони228>Такой мягкий и немного жидкий кот) #то что прислал всем клиентам сервак

АлахАкбр>Согласен!

Я так понимаю у этой проблемы два решения: стереть инпут у отправителя или чтобы сервер не слал отправителю по его нику. Только решение не одним не вторым способом я не знаю.
Так как в data который отсылает клиент серверу, все в куче, и разобрать где ник а где сам текст нельзя. Ниже код и клиента и сервера.

#####################################################################
КЛИЕНТ:
 def listen_server():
    while True:
        time1 = time.strftime("%Y-%m-%d(%H.%M.%S)", time.localtime())
        data = client.recv(2048)
        print("["+time1+"] "+data.decode("utf-8"))
def send_server():
    listen_thread = Thread(target=listen_server)
    listen_thread.start()
    while True:
        client.send(("              ").encode("utf-8"))
        client.send((name + "> " + input(":::")).encode("utf-8"))
        client.send(("              ").encode("utf-8"))
import socket, time
from threading import Thread
print("Твой код может состоять максимум из 8 символов, ид цифр и букв.")
name = input("Введите код: ")
n1 = len(name)
if n1 > 8:
    name[0:8]
if name == "123098":
    name = "Юра"
if name == "112233":
    name = "Федя"
run = True
client = socket.socket(
    socket.AF_INET,
    socket.SOCK_STREAM,
)
if run == True:
    client.connect(
        ("localhost", 25565)
    )
    client.send((f"К нам присоединился {name}").encode("utf-8"))
    run = False
if __name__ == '__main__':
    send_server()
#####################################################################
СЕРВЕР:
 def start():
    while True:
        user, adress = server.accept()
        user.send("Ты подключен к чату!\n".encode("utf-8"))
        user.send("".encode("utf-8"))
        print(f"К нам присоединился <{adress}>!")
        if user not in users:
            users.append(user)
        
        listen_accepted_user = threading.Thread(
            target=listen_user,
            args=(user,)
        )
        listen_accepted_user.start()
def listen_user(user):
    while True:
        data = user.recv(2048)
        print(f">> {data}")
        send_all(data)
def send_all(data):
    for user in users:
        user.send(data)
import socket, threading
server = socket.socket(
    socket.AF_INET,
    socket.SOCK_STREAM,
)
server.bind(
    ("127.0.0.1", 25565)
)
server.listen(5)
users = []
if __name__ == '__main__':
    start()
#####################################################################

Python для новичков » Python arcpy feature classes » Апрель 4, 2021 11:14:49

Работаю с 2 feature classes. У меня есть field- ‘Locality’ там только часть данных в него нужно добавить данные из другого feature class. К сожелению 2-feature class содержит Округа не участки как в 1-feature class.

Мне нужно использовать arcpy.SelectLayerByLocation_management с фунцией WITHIN чтобы найти малые участки внутру округов и довавить в field Locality в 1-feature class.

Я создал feature Layer который содержит все участки с пустыми строчками которые нужно заполнить, и feature Layer который содержит все округа.

Я не знаю что дальше делать как использовать эту функцию и обновить информацию об участках с “with arcpy.da.UpdateCursor”.

Python для новичков » Действие по звуку » Апрель 2, 2021 00:36:38

Здраствуйте, хочу написать бота для рыбалки в игре. Хотел бы поинтересоваться как мне сделать так, чтобы когда в игре воспроизводился определенный звук производилось какое-то действие(нажатие правой кнопки мыши)

Python для новичков » Интеграция программы в telegram бота » Апрель 1, 2021 11:16:02

У меня есть программа эмулятор игральных кубиков, он там делает броски с различными гранями и т. д, но это не важно. Я хочу её интегрировать в Telegram бота. Я уже начал это делать, но столкнулся с проблемой. Я не могу в @bot.message_handler(content_types сделать вычисления, а потом в @bot.callback_query_handler(func=lambda call: True) эти вычисления отправлять.

Я скину код, кто может наведите на верный путь


BOT телеграм:

 import config
import telebot
from telebot import types
bot = telebot.TeleBot(config.token)
@bot.message_handler(commands=['start'])
def welcome(message):
    #keyboard
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    item1 = types.KeyboardButton('База данных')
    item2 = types.KeyboardButton('Генератор паролей')
    item3 = types.KeyboardButton('Эмулятор игральных кубиков')
    markup.add(item1,item2,item3)
    bot.send_message(message.chat.id,'Добро пожаловать, {0.first_name}!\nЯ - <b>{1.first_name}</b>'.format(message.from_user,bot.get_me()),
                     parse_mode='html', reply_markup=markup)
@bot.message_handler(content_types=['text'])
def replayter(message):
    global hap
    if message.chat.type == 'private':
        if message.text == 'База данных':
            markup = types.InlineKeyboardMarkup(row_width=2)
            item1 = types.InlineKeyboardButton('Общий балл', callback_data='1')
            item2 = types.InlineKeyboardButton('Добавить учеников', callback_data='2')
            item3 = types.InlineKeyboardButton('Удалить ученика', callback_data='3')
            item4 = types.InlineKeyboardButton('Изменить данные ученика', callback_data='4')
            item5 = types.InlineKeyboardButton('Распечатать базу данных', callback_data='5')
            item6 = types.InlineKeyboardButton('Поиск по возрасту', callback_data='6')
            item7 = types.InlineKeyboardButton('Поиск по баллу', callback_data='7')
            markup.add(item1, item2, item3, item4, item5,item6,item7)
            bot.send_message(message.chat.id, 'Какую операцию Вы хотите выполнить?', reply_markup=markup)
        elif message.text == "Генератор поролей":
            markup = types.InlineKeyboardMarkup(row_width=2)
            item1 = types.InlineKeyboardButton('Сгенерировать', callback_data='8')
            markup.add(item1)
            bot.send_message(message.chat.id, 'Какую операцию Вы хотите выполнить?', reply_markup=markup)
        elif message.text == "Эмулятор игральных кубиков":
            global hap
            global results
            n = bot.send_message(message, 'Введите количество граней куба: '.format(message.from_user, bot.get_me()))
            z = bot.send_message(message.chat.id, 'Введите количество кубов: '.format(message.from_user, bot.get_me()))
            g = bot.send_message(message.chat.id,'Введите количество бросков: '.format(message.from_user, bot.get_me()))
            sp = [n,z,g]
            hap = []
            for i in range(sp[2]):
                hap.append([])
                for j in range(sp[1]):
                    d = randrange(1, sp[0] + 1)
                    hap[i].append(d)
            results = []
            for i in hap:
                results.append(sum(i))
            markup = types.InlineKeyboardMarkup(row_width=2)
            item1 = types.InlineKeyboardButton('Вывести результаты всех кубиков', callback_data='9')
            item2 = types.InlineKeyboardButton('Вывести результаты всех бросков', callback_data='10')
            item3 = types.InlineKeyboardButton('Вывести максимальную сумму', callback_data='11')
            item4 = types.InlineKeyboardButton('Вывести минимальную сумму', callback_data='12')
            item5 = types.InlineKeyboardButton('Увеличить результат броска', callback_data='13')
            markup.add(item1,item2,item3,item4,item5)
            bot.send_message(message.chat.id, 'Какую операцию Вы хотите выполнить?', reply_markup=markup)
        else:
            bot.send_message(message.chat.id, 'Я таких слов не знаю(')
@bot.callback_query_handler(func=lambda call: True)
def callback_inline(call):
    try:
        if call.message:
            if call.data == '1':
                pass
            elif call.data == '2':
                pass
            elif call.data == '3':
                pass
            elif call.data == '4':
                pass
            elif call.data == '5':
                pass
            elif call.data == '6':
                pass
            elif call.data == '7':
                pass
            elif call.data == '8':
                pass
            elif call.data == '9':
                bot.send_message(call.message.chat.id,str(*hap))
            elif call.data == '10':
                pass
            elif call.data == '11':
                pass
            elif call.data == '12':
                pass
            elif call.data == '13':
                pass
            bot.edit_message_text(chat_id= call.message.chat.id, message_id=call.message.message_id, text='База данных',reply_markup=None)
            bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text='Генератор поролей',
                                  reply_markup=None)
            bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text='Эмулятор игральных кубиков',
                                  reply_markup=None)
            bot.answer_callback_query(chat_id=call.message.chat.id, show_alert=True,text = 'Тест')
    except Exception as r:
        print(repr(r))
bot.polling(none_stop=True)




Программа,которую я хочу интегрировать:

 from random import randrange
# -*- coding: utf-8 -*-
def wyw():  #ввод данных
    n = int(input('Введите количество граней куба: '))
    z = int(input('Введите количество кубов: '))
    g = int(input('Введите количество бросков: '))
    return [n, z, g]
def f_results():   # результаты бросков
    global results
    results = []
    for i in hap:
        results.append(sum(i))
    return results
def act():    #генератор случайных бросков
    global hap
    sp = wyw()
    hap = []
    for i in range(sp[2]):
        hap.append([])
        for j in range(sp[1]):
            d = randrange(1, sp[0] + 1)
            hap[i].append(d)
    return hap
act()
f_results()
menu_commands ='Какую операцию Вы хотите выполнить?\n1) Вывести результаты всех кубиков\n2) Вывести результаты всех бросков\n3) Вывести максимальную сумму\n4) Вывести минимальную сумму\n5) Увеличить результат броска\n6) Уменьшить результат броска\n7) Вывести файл со значениями бросков\n8) Выйти из программы\nВведите номер операции: '
menu = int(input(menu_commands))
while 0<menu<8:
    if menu == 1:
        print(*hap)
        menu = int(input(menu_commands))
    if menu == 2:
        print(*results)
        menu = int(input(menu_commands))
    if menu == 3:
        def mx():  # максимальный результат
            return max(results)
        print(mx())
        menu = int(input(menu_commands))
    if menu == 4:
        def mn():  # минимальный результат
            return min(results)
        print(mn())
        menu = int(input(menu_commands))
    if menu == 5:
        def pribavit_k_brosku():
            pribav = int(input('Введите число, которое хотите прибавить: '))
            ind = int(input('К какому броску вы хотите прибавить? (введите числом): ')) - 1
            global results
            results[ind] = results[ind] + pribav
            return results
        print(*pribavit_k_brosku())
        menu = int(input(menu_commands))
    if menu == 6:
        def otnyat_ot_broska():
            vichet = int(input('Введите число, которое хотите отнять: '))
            ind = len(hap) + 1
            while ind >= len(hap):
                ind = int(input('Из какого броска вы хотите отнять? (введите числом): ')) - 1
            results[ind] = results[ind] - vichet
            return results
        print(*otnyat_ot_broska())
        menu = int(input(menu_commands))
    if menu == 7:
        def log():
            f = open('cubelog.txt', 'a+', encoding='utf-8')
            f.write(f'{str(hap)}\n\n')
            f.close()
        log()
        menu = int(input(menu_commands))
print('Программа завершена')