PySide開發MySql遠程備份工具

MySql數據庫安裝在機房,而工作人員日常辦公的地方距離機房有段距離,且不在同一樓層。出入機房不是很方便。就想著能否給這些人員開發一個圖形化的備份MySql數據庫的小工具?
使用組件如下:
(1)Python
(2)PySide
(3)mysqldump
其實mysql已經提供了一個mysqldump.exe來做mysql數據庫的備份,也支持遠程操作,但因為是命令行形式的,對于普通的工作人員來說使用起來就非常不方便了,這個小工具的原理就是使用PySide對mysqldump.exe做一封裝,提供GUI接口。
里面值得注意的是Thread和subprocess的結合,具體詳見如下代碼:

ContractedBlock.gifExpandedBlockStart.gifView Code
########################################################################
class BackupThread(QThread):
"""備份數據庫線程"""
dataReady
= Signal(object)
config
= ApplicationConfig()
#----------------------------------------------------------------------
def run(self):
"""具體執行部分"""
self.dataReady.emit(u
"正在執行,請稍后......")
#加載配置信息
self.config.load()
#組織備份數據庫所需要的命令
filestamp= time.strftime("%Y-%m-%d")

filename
= "%s-%s.sql" % (self.config.databasename, filestamp)
filename
= os.path.join(self.config.backupdir, filename)
mysqldumpfile
= os.path.join(os.getcwd(), "mysqldump.exe")
command
= "%s -u %s -p%s -h %s -e --opt -c %s" % (mysqldumpfile, self.config.user, self.config.password, self.config.remoteIp, self.config.databasename)
print command
pipe
= subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#print pipe.stdout.readlines()
#promptMsg= "".join(pipe.stdout.readlines())
#print "promptMsg is:", promptMsg
fp= open(filename, "w")
item
= None
for line in pipe.stdout:
fp.writelines(line)
self.dataReady.emit(line)
fp.close()
completeMsg
= "";
#取出最后一個item,判斷里面的內容是否包含
if item is not None:
text
= item.text()
if text.find("Dump completed") > 0:
print "Completed"
completeMsg
= u"開始壓縮,請稍后......"
#計算壓縮后的文件名
compressedfilename= os.path.splittext(filename)[0] + ".zip"
if self.compress(filename, compressedfilename):
completeMsg
= u"壓縮文件出錯,請檢查!"
else:
completeMsg
= u"操作已完成,請檢查!"
else:
completeMsg
= u"操作過程中出現錯誤,請檢查!"
else:
completeMsg
= u"操作過程中出現錯誤,請檢查!"

self.dataReady.emit(completeMsg)

全部代碼如下所示:
(1)ApplicationConfig.py

ContractedBlock.gifExpandedBlockStart.gifView Code
#-*-coding:utf-8-*-

import ConfigParser


########################################################################
class ApplicationConfig:
"""
程序相關配置信息
"""

#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.remoteIp
= "127.0.0.1"
self.remotePort
= "3306"
self.user
= "root"
self.password
= ""
self.databasename
= ""
self.backupdir
= "c:\\"
self.config
= ConfigParser.ConfigParser()

#----------------------------------------------------------------------
def load(self):
"""
加載配置信息
"""
try:
self.config.read(r
".\ApplicationConfig.cfg")
self.remoteIp
= self.config.get("mysql", "remoteip")
self.remotePort
= self.config.get("mysql", "remoteport")
self.user
= self.config.get("mysql", "user")
self.password
= self.config.get("mysql", "password")
self.databasename
= self.config.get("mysql", "databasename")
self.backupdir
= self.config.get("mysql", "backupdir")
except Exception as ex:
print "Some exception occured when invoke load(), exception message is ", ex, " please check it !"

#----------------------------------------------------------------------
def save(self):
"""
保存配置信息
"""
self.config.read(r
".\ApplicationConfig.cfg")
if "mysql" not in self.config.sections():
self.config.add_section(
"mysql")
self.config.set(
"mysql", "remoteip", self.remoteIp)
self.config.set(
"mysql", "remoteport", self.remotePort)
self.config.set(
"mysql", "user", self.user)
self.config.set(
"mysql", "password", self.password)
self.config.set(
"mysql", "databasename", self.databasename)
self.config.set(
"mysql", "backupdir", self.backupdir)
fp
= open(r".\ApplicationConfig.cfg", "w")
self.config.write(fp)
#----------------------------------------------------------------------
def __str__(self):
"""
返回相應的字符串表示
"""
description
= "remoteip : \t" + self.remoteIp + "\n" + \
"user : \t" + self.user + "\n" +\
"password : \t"+ self.password+ "\n"+ \
"databasename \t" + self.databasename + "\n" + \
"backupdir : \t" + self.backupdir + "\n"
return description
(2)MainForm.py
ContractedBlock.gifExpandedBlockStart.gifView Code
# -*- coding: utf-8 -*-

import sys
reload(sys)
sys.setdefaultencoding(
'utf-8')

from PySide.QtCore import *
from PySide.QtGui import *
import os
import time
import subprocess
import zipfile


from ApplicationConfig import ApplicationConfig

class ConfigurationPage(QWidget):
def __init__(self, parent=None):
super(ConfigurationPage, self).
__init__(parent)
self.configGroup
= QGroupBox(u"相關配置信息")

self.remoteIPLabel
= QLabel(u"數據庫所在IP地址:")
self.editRemoteIP
= QLineEdit(u"數據庫所在IP地址")
self.remotePortLabel
= QLabel(u"使用端口:")
self.editPort
= QLineEdit(u"使用端口")
self.userLabel
= QLabel(u"用戶名:")
self.editUser
= QLineEdit(u"用戶名")
self.passwordLabel
= QLabel(u"密碼:")
self.editPassword
= QLineEdit(u"密碼")
self.dabasenameLabel
= QLabel(u"數據庫名:")
self.editDatabaseName
= QLineEdit(u"數據庫名")
self.backupdirLabel
= QLabel(u"備份文件存放目錄:")
self.editBackupDir
= QLineEdit(u"備份文件存放目錄")
self.browseButton
= QPushButton(u"瀏覽")
self.browseButton.clicked.connect(self.onBrowse)

self.paremeterLayout
= QGridLayout();
self.paremeterLayout.addWidget(self.remoteIPLabel, 0, 0)
self.paremeterLayout.addWidget(self.editRemoteIP, 0,
1, 1, 2)
self.paremeterLayout.addWidget(self.remotePortLabel,
1, 0)
self.paremeterLayout.addWidget(self.editPort,
1, 1, 1, 2)
self.paremeterLayout.addWidget(self.userLabel,
2, 0)
self.paremeterLayout.addWidget(self.editUser,
2, 1, 1, 2)
self.paremeterLayout.addWidget(self.passwordLabel,
3, 0)
self.paremeterLayout.addWidget(self.editPassword,
3, 1, 1, 2)
self.paremeterLayout.addWidget(self.dabasenameLabel,
4, 0)
self.paremeterLayout.addWidget(self.editDatabaseName,
4, 1, 1, 2)
self.paremeterLayout.addWidget(self.backupdirLabel,
5, 0)
self.paremeterLayout.addWidget(self.editBackupDir,
5, 1)
self.paremeterLayout.addWidget(self.browseButton,
5, 2)

self.btnSave
= QPushButton(u"保存")
self.btnSave.setMinimumHeight(
50)
self.btnSave.clicked.connect(self.onSave)

self.configGroup.setLayout(self.paremeterLayout)

self.mainLayout
= QVBoxLayout()
self.mainLayout.addWidget(self.configGroup)
self.mainLayout.addSpacing(
20)
self.mainLayout.addWidget(self.btnSave)
self.mainLayout.addStretch(
1)

self.setLayout(self.mainLayout)

self.config
= ApplicationConfig()
self.doInitialize()
#----------------------------------------------------------------------
def onSave(self):
"""保存處理"""
try:
self.config.remoteIp
= self.editRemoteIP.text()
self.config.remotePort
= self.editPort.text()
self.config.user
= self.editUser.text()
self.config.password
= self.editPassword.text()
self.config.databasename
= self.editDatabaseName.text()
self.config.backupdir
= self.editBackupDir.text()
self.config.save()
except:
print "some exceptions occured when invoke onSave() method, please check it!"
#print unicode(self.config.remoteIp)
#----------------------------------------------------------------------
def onBrowse(self):
"""選擇目錄"""
directory
= QFileDialog.getExistingDirectory(self, u"查找備份目錄",
QDir.currentPath())
if directory:
self.editBackupDir.setText(directory)

#----------------------------------------------------------------------
def doInitialize(self):
"""初始化相關參數"""
self.config.load()
self.editRemoteIP.setText(unicode(self.config.remoteIp))
self.editPort.setText(unicode(self.config.remotePort))
self.editUser.setText(unicode(self.config.user))
self.editPassword.setText(unicode(self.config.password))
self.editDatabaseName.setText(unicode(self.config.databasename))
self.editBackupDir.setText(unicode(self.config.backupdir))


########################################################################
class BackupThread(QThread):
"""備份數據庫線程"""
dataReady
= Signal(object)
config
= ApplicationConfig()
#----------------------------------------------------------------------
def run(self):
"""具體執行部分"""
self.dataReady.emit(u
"正在執行,請稍后......")
#加載配置信息
self.config.load()
#組織備份數據庫所需要的命令
filestamp= time.strftime("%Y-%m-%d")

filename
= "%s-%s.sql" % (self.config.databasename, filestamp)
filename
= os.path.join(self.config.backupdir, filename)
mysqldumpfile
= os.path.join(os.getcwd(), "mysqldump.exe")
command
= "%s -u %s -p%s -h %s -e --opt -c %s" % (mysqldumpfile, self.config.user, self.config.password, self.config.remoteIp, self.config.databasename)
print command
pipe
= subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#print pipe.stdout.readlines()
#promptMsg= "".join(pipe.stdout.readlines())
#print "promptMsg is:", promptMsg
fp= open(filename, "w")
item
= None
for line in pipe.stdout:
fp.writelines(line)
self.dataReady.emit(line)
fp.close()
completeMsg
= "";
#取出最后一個item,判斷里面的內容是否包含
if item is not None:
text
= item.text()
if text.find("Dump completed") > 0:
print "Completed"
completeMsg
= u"開始壓縮,請稍后......"
#計算壓縮后的文件名
compressedfilename= os.path.splittext(filename)[0] + ".zip"
if self.compress(filename, compressedfilename):
completeMsg
= u"壓縮文件出錯,請檢查!"
else:
completeMsg
= u"操作已完成,請檢查!"
else:
completeMsg
= u"操作過程中出現錯誤,請檢查!"
else:
completeMsg
= u"操作過程中出現錯誤,請檢查!"

self.dataReady.emit(completeMsg)

########################################################################
class BackupPage(QWidget):
""""""

#----------------------------------------------------------------------
def __init__(self, parent=None):
"""Constructor"""
super(BackupPage, self).
__init__(parent)
self.backupButton
= QPushButton(u"備份數據庫")
self.backupButton.setMinimumHeight(
50)
self.backupButton.clicked.connect(self.doBackupOperation)
self.labelPrompt
= QLabel(u"提示信息") #執行結果顯示
self.listPrompt = QListWidget()
self.labelPrompt.setWordWrap(True)
self.layout
= QVBoxLayout()
self.layout.addStretch()
self.layout.addWidget(self.backupButton)
#self.layout.addSpacing(20)
self.layout.addWidget(self.labelPrompt)
self.layout.addWidget(self.listPrompt)
self.layout.addStretch()
self.config
= ApplicationConfig()
self.thread
= BackupThread() #備份線程
self.thread.dataReady.connect(self.updateUI, Qt.QueuedConnection)
self.setLayout(self.layout)
#----------------------------------------------------------------------
def doBackupOperation(self):
"""執行備份數據庫的任務"""
#self.labelPrompt.setText(u"正在執行,請稍后......")
##加載配置信息
#self.config.load()
##組織備份數據庫所需要的命令
#filestamp= time.strftime("%Y-%m-%d")

#filename = "%s-%s.sql" % (self.config.databasename, filestamp)
#filename = os.path.join(self.config.backupdir, filename)
#mysqldumpfile = os.path.join(os.getcwd(), "mysqldump.exe")
#command= "%s -u %s -p%s -h %s -e --opt -c %s" % (mysqldumpfile, self.config.user, self.config.password, self.config.remoteIp, self.config.databasename)
#print command
#pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#fp= open(filename, "w")
#item = None
#for line in pipe.stdout:
#fp.writelines(line)
#item = QListWidgetItem(line)
#self.listPrompt.addItem(item)
#if self.listPrompt.count() > 0:
#self.listPrompt.setCurrentRow(self.listPrompt.count() - 1)
#pass
#fp.close()
#self.listPrompt.setFocus()
#completeMsg= "";
##取出最后一個item,判斷里面的內容是否包含
#if item is not None:
#text= item.text()
#if text.find("Dump completed") > 0:
#print "Completed"
#completeMsg = u"開始壓縮,請稍后......"
##計算壓縮后的文件名
#compressedfilename= os.path.splittext(filename)[0] + ".zip"
#if self.compress(filename, compressedfilename):
#completeMsg = u"壓縮文件出錯,請檢查!"
#else:
#completeMsg = u"操作已完成,請檢查!"
#else:
#completeMsg = u"操作過程中出現錯誤,請檢查!"
#else:
#completeMsg = u"操作過程中出現錯誤,請檢查!"
#self.labelPrompt.setText(completeMsg)

self.thread.start()
#啟動線程
#----------------------------------------------------------------------
def updateUI(self, data):
"""更新UI部分處理"""
item
= QListWidgetItem(data)
self.listPrompt.addItem(data)
self.listPrompt.setFocus()
#----------------------------------------------------------------------
def compress(self, infilename, dstfilename, level = 9):
"""壓縮"""
result
= False;
try:
zfile
= zipfile.ZipFile(dstfilename, "w")
zfile.write(infilename, os.path.split(infilename)[
1])
zfile.close()
result
= True
except:
print "some error occured when invoke (), please check it!"
result
= False

return result;


########################################################################
class HelpPage(QWidget):
""""""

#----------------------------------------------------------------------
def __init__(self, parent=None):
"""Constructor"""
super(HelpPage, self).
__init__(parent)
self.helpLabel
= QLabel(u"使用說明:\n\t"
u
"(1)備份數據前請檢查相關配置信息是否正確\n\t"
u
"(2)點擊備份數據庫按鈕,等待本分操作完成\n\t"
u
"(3)請留意備份過程中是否有錯誤信息\n\t")

self.layout
= QVBoxLayout()
self.layout.addSpacing(
10)
self.layout.addWidget(self.helpLabel)
self.layout.addStretch(
1)

self.setLayout(self.layout)

class MainDialog(QDialog):
#----------------------------------------------------------------------
def __init__(self, parent=None):
"""初始化函數
"""
super(MainDialog, self).
__init__(parent)

#Create Widgets

self.contentsWidget
= QListWidget()
self.contentsWidget.setViewMode(QListView.IconMode)
self.contentsWidget.setIconSize(QSize(
96, 84))
self.contentsWidget.setMovement(QListView.Static)
self.contentsWidget.setMaximumWidth(
128 + 10)
self.contentsWidget.setMinimumHeight((
84 + 12 ) * 4)
self.contentsWidget.setSpacing(
12)

self.pagesWidget
= QStackedWidget()
self.pagesWidget.addWidget(ConfigurationPage())
self.pagesWidget.addWidget(BackupPage())
self.pagesWidget.addWidget(HelpPage())

self.closeButton
= QPushButton(u"退出")

self.createIcons()
self.contentsWidget.setCurrentRow(0)

self.closeButton.clicked.connect(self.close)

self.horizontalLayout
= QHBoxLayout()
self.horizontalLayout.addWidget(self.contentsWidget)
self.horizontalLayout.addWidget(self.pagesWidget,
1)

self.buttonsLayout
= QHBoxLayout()
self.buttonsLayout.addStretch(
1)
self.buttonsLayout.addWidget(self.closeButton)

self.mainLayout
= QVBoxLayout()
self.mainLayout.addLayout(self.horizontalLayout)
self.mainLayout.addSpacing(
12)
self.mainLayout.addLayout(self.buttonsLayout)

self.setLayout(self.mainLayout)

#Add button
self.setWindowTitle(u"數據庫備份")

def changePage(self, current, previous):
if not current:
current
= previous

self.pagesWidget.setCurrentIndex(self.contentsWidget.row(current))

def createIcons(self):
configButton
= QListWidgetItem(self.contentsWidget)
configButton.setIcon(QIcon(
'./images/config.png'))
configButton.setText(u
"相關配置信息")
configButton.setTextAlignment(Qt.AlignHCenter)
configButton.setFlags(Qt.ItemIsSelectable
| Qt.ItemIsEnabled)

updateButton
= QListWidgetItem(self.contentsWidget)
updateButton.setIcon(QIcon(
'./images/update.png'))
updateButton.setText(u
"備份")
updateButton.setTextAlignment(Qt.AlignHCenter)
updateButton.setFlags(Qt.ItemIsSelectable
| Qt.ItemIsEnabled)

queryButton
= QListWidgetItem(self.contentsWidget)
queryButton.setIcon(QIcon(
'./images/query.png'))
queryButton.setText(u
"使用說明")
queryButton.setTextAlignment(Qt.AlignHCenter)
queryButton.setFlags(Qt.ItemIsSelectable
| Qt.ItemIsEnabled)

self.contentsWidget.currentItemChanged.connect(self.changePage)

if __name__ == "__main__":
app
= QApplication(sys.argv)
form
= MainDialog()
form.show()
sys.exit(app.exec_())
(3)配置文件ApplicationConfig.cfg
ContractedBlock.gifExpandedBlockStart.gifView Code
[mysql]
remoteport
= 3306
remoteip
= 10.88.81.96
databasename
= test
password
= root
backupdir
= E:/Study/Python/MySqlAssistant
user
= root
執行MainForm.py即可
如果要編譯成exe,可采用py2exe,或者cx_freeze進行編譯

轉載于:https://www.cnblogs.com/Jerryshome/archive/2011/05/10/2042136.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378440.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378440.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378440.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HadoopSourceAnalyse --- Nodemanager Container request handler

Overview Container 是Hadoop中運行任務的地方,當Resourcemanager收到一任務請求后,會向nodemanager 請求一個Container 來運行ApplicationMaster, ApplicationMaster運行起來之后,會繼續向Resourcemanager請求新的container來運行…

數據結構 二叉樹的存儲結構_線程二叉樹| 數據結構

數據結構 二叉樹的存儲結構線程二叉樹 (Threaded Binary Tree ) A binary tree can be represented by using array representation or linked list representation. When a binary tree is represented using linked list representation. If any node is not having a child …

七、有機硅柔軟劑在不同發展階段分子結構特征及主要解決的問題?

有機硅柔軟劑在不同發展階段分子結構特征及主要解決的問題? 收集資料階段 聚有機硅氧烷具有低表面能、優良的潤滑性、熱穩定性和疏水性。從分子層面分析,經聚有機硅氧烷處理的織物,其柔軟性來自硅氧烷骨架中 Si—O—Si鍵的 360自由旋轉及甲基之間的低相互作用。因此,聚有機…

【智能車Code review】——拐點的尋找

博主聯系方式: QQ:1540984562 QQ交流群:892023501 群里會有往屆的smarters和電賽選手,群里也會不時分享一些有用的資料,有問題可以在群里多問問。 系列文章 【智能車Code review】—曲率計算、最小二乘法擬合 【智能車Code review】——坡道圖像與控制處理 【智能車Code re…

linux 單例模式改密碼,Java 利用枚舉實現單例模式

引言單例模式比較常見的實現方法有懶漢模式,DCL模式公有靜態成員等,從Java 1.5版本起,單元素枚舉實現單例模式成為最佳的方法。Java枚舉基本用法枚舉的用法比較多,本文主要旨在介紹利用枚舉實現單例模式的原理,所以這里…

編碼簡介

編碼簡介最近被字符集搞得頭大,基于為自己掃盲的目的,索性收集資料研究一下,現將各方資料歸納成本文。這里并不想把復雜的規則說明一大通。如有需要,請參照其他資料或本文給出的參考資料。 如有錯誤,歡迎指正。…

2013年5月7日---JS中的正則

/*(1)RegExp對象的test方法------------------C#中的isMatchvar num1d23; //一個字符串var regnew RegExp(^\\d$); //準備正則alert(reg.test(num)); //開始匹配并彈出--false*//*(2)ReExp對象的test方法var num123;var regnew RegExp(/^\d$/);ale…

八、關于防水透濕整理

1,防水透濕整理加工技術的類型? 收集資料階段 按照加工方式分類 防水透濕織物按照加工方式可分為高密織物、涂層織物和層壓織物。不同加工方式所對應的織物各有特色。高密織物產生于 20 世紀 80 年代,它的密度可達到普通織物的 20 倍。在晴朗天氣時,紗線孔隙大約為 10 μm…

linux qt 音頻文件怎么打開,Qt:獲取Linux中可用音頻設備的列表

我想要獲取我的Linux系統上可用的所有音頻設備的列表。然后我會將這個列表顯示在一個組合框中,用戶將從中選擇用于錄制/播放的設備。根據用戶的選擇,我將構建QAudioInput和QAudioOutput進行錄制/播放。Qt:獲取Linux中可用音頻設備的列表根據Q…

c# uri.host_C#| Uri.GetLeftPart()方法與示例

c# uri.hostUri.GetLeftPart()方法 (Uri.GetLeftPart() Method) Uri.GetLeftPart() method is an instance method that is used to get a specified part from the given URI based on passed UriPartial enum. Uri.GetLeftPart()方法是一個實例方法,用于基于傳遞的…

求質數算法的N種境界 (N 10) zz

★引子 前天,俺在《俺的招聘經驗[4]:通過筆試答題能看出啥?》一文,以"求質數"作為例子,介紹了一些考察應聘者的經驗。由于本文沒有政治敏感內容,順便就轉貼到俺在CSDN的鏡像博客。   昨天&…

【智能車Code review】——小S與中S道路判斷

博主聯系方式: QQ:1540984562 QQ交流群:892023501 群里會有往屆的smarters和電賽選手,群里也會不時分享一些有用的資料,有問題可以在群里多問問。 系列文章 【智能車Code review】—曲率計算、最小二乘法擬合 【智能車Code review】——坡道圖像與控制處理 【智能車Code re…

Python匿名函數---排序

一、列表的排序 nums [1,2,3,5,4,7,87,4,9,56,44,7,5] nums.sort()#默認從小到大排序 nums#結果為:[1, 2, 3, 4, 4, 5, 5, 7, 7, 9, 44, 56, 87]nums [1,2,3,5,4,7,87,4,9,56,44,7,5] nums.sort(reverseTrue)#從大到小排序 nums#結果為:[87, 56, 44, …

linux 內核編譯需要多大空間,編譯2.6.28內核出錯。。。。空間不足。而/tmp/還有好幾G...

編譯2.6.28內核出錯。。。。空間不足。而/tmp/還有好幾G發布時間:2009-01-02 16:56:47來源:紅聯作者:weixq316今天閑來無事,就去下載了最新的內核--2.6.28來編譯安裝。。。:0)1放在/usr/src/2.6.28/中編譯。。。。。我的/usr還有1G多的空間。…

如何用vi 復制第5行到第10行并粘貼到第12行之后

方法一: 光標放到第五行,輸入:y6y光標放到第12行,輸入:p方法二:命令行模式下輸入:5,10 co 12方法三:延伸一下, 有時候不想費勁看多少行或復制大量行時,可以使用標簽來替代光標移到起…

go zap去除程序名稱_適用于Zip,Zap和Zoom游戲的Python程序

go zap去除程序名稱Write a python program that displays a message as follows for a given number: 編寫一個python程序,顯示給定數字的消息如下: If it is a multiple of three, display "Zip". 如果是三的倍數,則顯示“ Zip…

【智能車Code review】——環島的判定與補線操作

博主聯系方式: QQ:1540984562 QQ交流群:892023501 群里會有往屆的smarters和電賽選手,群里也會不時分享一些有用的資料,有問題可以在群里多問問。 視頻講解 這里是對于代碼的講解視頻,大約一個小時,需要的同學可以看看:B站:meeting_01 系列文章 【智能車Code review】…

Python交換兩個變量的三種方法

一、借助于第三個變量(很常用) a 5 b 6c 0 c a a b b c print("a%d,b%d"%(a,b))#結果為:a6,b5二、如何不借助第三個變量實現兩個變量交換數據呢? a 5 b 6a ab b a-b a a-b print("a%d,b%d"%(a,b))#結果為:a…

linux下怎么查kill某個進程,Linux下查詢進程PS或者殺死進程kill的小技巧

假設我們要kill掉tomcat:那么我們首先需要tomcat的進程號pid:ps -aux | grep tomcat記下tomcat的PID后,執行:kill PID(tomcat)好了,就到這里....路人甲:小的們,滅了這個欺騙人民情感的家伙&…

【筆記】VB控件MSComm功能介紹

VB中的MSComm 控件通過串行端口傳輸和接收數據,為應用程序提供串行通訊功能。MSComm控件在串口編程時非常方便,程序員不必去花時間去了解較為復雜的API函數,而且在VC、VB、Delphi等語言中均可使用。 Microsoft Communications Control&#x…