0

私はPythonでプログラムに取り組んでおり、少し問題があります。私のプログラムがすべきことは、ファイルから行を読み取り、それを解析し、その行の一部を文字列に書き込むことです。次に、別のファイルでその文字列を検索し、見つかったときにその行を出力します。次に、最初のファイルの次の行に移動し、最初のファイルのすべての行が読み取られるまでプロセスを繰り返します。

これを行うための私のコードは次のとおりです。

def readermain():
    """called if constant file exists"""

    for line in portslist: #reads printer port list and parses name and port address 
        marker = line.split()
        printername=marker[0]
        address=marker[1]

        for lines in constantfile:
            if address in lines: #if the desired address is in the line
                lineholder=lines.split()
                print (lineholder)
                oldonline=lineholder[4]
                oldutc=lineholder[5]
                status=lineholder[2]
                address=lineholder[1]

問題は、最初for line in portslistの行が次の行に移動していないように見えることです。同じ行を何度も出力します。portslistとと の両方のリストは、 etc をconstantfile使用するプログラムの他の場所で宣言されています。constantfile=open("constantfile.dat").readlines()ヘルプや提案は大歓迎です。

プログラム自体はかなり長いので、問題領域を要約するのに疲れましたが、以下に投稿します。これは進行中の作業であるため、私が認識している他の問題があります。はい、読みやすさの最良の例ではありません. それでも提案は素晴らしいです。

"""Program to pull down list of printers and ping each to see if it is online. 
Will track printers over time, if printer has been offline for over a year it will be listed in a delete file.
This program is designed to run on windows and requires python to be installed. """

import win32com.client, os, time, datetime
from datetime import datetime




computername="(name goes here)"
currentdate=datetime.now()
currentdateutc= (time.mktime(currentdate.timetuple()))

def getPorts(computername):
    """Gets printer name and port name"""

    portslist= open("printerports.txt","w")

    objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
    objSWbemServices = objWMIService.ConnectServer(computername,"root\cimv2") 
    colItems = objSWbemServices.ExecQuery("Select * from Win32_Printer") 
    for objItem in colItems:
        list= objItem.Name + " " + objItem.PortName+"\n"
        portslist.write(list)

    portslist.close()

def pingone(address):
    """Pings address and returns 0 if it is online"""
    pingreturn=os.system("ping -n 1 " + address)
    return (pingreturn)

def pingfive(address):
    """Pings as address five times"""
    pingreturn=os.system("ping -n 5 " + address)
    return (pingreturn)

def online(printername, address, currentdate):
    return str((printername +" at port "+ address+" is online on "+ str(currentdate)+"\n"))

def offline(printername, address, currentdate):
    return str((printername +" at port "+address+" is offline on "+ str(currentdate)+"\n"))

def constantonline(printername, address, currentdate, currentdateutc):
    return str((printername+" "+address+" "+str(0)+" "+str(currentdate)+" "+str(currentdate)+" "+str(currentdateutc)+"\n"))

def constantoffline(printername, address, currentdate, oldonline, oldutc):
    return str((printername+" "+address+" "+str(1)+" "+str(currentdate)+" "+str(oldonline)+" "+str(oldutc)+"\n"))

def removal(printername, address, oldonline):
    return str((printername+" with queue "+address+" has been offline since "+str(oldonline)+"\n"))

def constantfilecheck():
    """Checks for constant file"""
    if os.path.isfile("constantfile.dat")==True:  #checks if a constant file exists. if not one is made
        return True

    else:
        return False

def readermain(portslist, constantfile, counter, oncounter, offcounter):
    """called if constant file exists"""

    for line in portslist: #reads printer port list and parses name and port address 
        print(line)
        marker = line.split()
        printername=marker[0]
        address=marker[1]

        for lines in constantfile:
            print(lines)
            if address in lines: #if the desired address is in the line
                lineholder=lines.split()
                print (lineholder)
                oldonline=lineholder[4]
                oldutc=lineholder[5]
                status=lineholder[2]
                address=lineholder[1]
                #--------------------------------------------------------------------------------------------------------------------------------------------
                print ("Address found in constant file")

                if pingone(address)==0:
                    newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                    onlinefile.write(online(printername, address, currentdate))
                    oncounter += 1
                    counter += 1

                else:
                    if pingfive(address)==0:
                        newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                        onlinefile.write(online(printername, address, currentdate))
                        oncounter += 1
                        counter += 1

                    else:
                        newconstantfile.write(constantoffline(printername, address, currentdate, oldonline, oldutc))
                        offlinefile.write(offline(printername, address, currentdate))
                        offcounter += 1
                        counter += 1
                        if status == 0 and (currentdateutc-oldutc)>=31556926:
                            #-----------------------------------------------------------------------------------------------------------------------------------
                            print("printer older than year")
                            deletefile=open("removefile.txt", "a")
                            deletefile.write(removal(printername, address, oldonline))
                            deletefile.close()
            else:
                #not in constant file
                #------------------------------------------------------------------------------------------------------------------------------------------------
                print("not in constant file")
                if pingone(address)==0:
                    newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                    onlinefile.write(online(printername, address, currentdate))
                    oncounter += 1
                    counter += 1

                else:
                    if pingfive(address)==0:
                        newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                        onlinefile.write(online(printername, address, currrentdate))
                        oncounter += 1
                        counter += 1

                    else:
                        newconstantfile.write(printername+" "+address+" "+str(1)+" "+str(currentdate)+" "+str(oldonline)+" "+str(currentdateutc)+"\n")
                        offlinefile.write(offline(printername, address, currentdate))
                        offcounter += 1
                        counter += 1

def readersecondary(oncounter, offcounter, counter):
    """called if no constant file exists already"""

    for line in portslist: #reads printer port list and parses name and port address 

        marker = line.split()
        printername=marker[0]
        address=marker[1]

        if pingone(address)==0:
            newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
            onlinefile.write(online(printername, address, currentdate))
            oncounter += 1
            counter += 1

        else:
            if pingfive(address)==0:
                newconstantfile.write(constantonline(printername, address, currentdate, currentdateutc))
                onlinefile.write(online(printername, address, currrentdate))
                oncounter += 1
                counter += 1

            else:
                newconstantfile.write(printername+" "+address+" "+str(1)+" "+str(currentdate)+" "+str(currentdate)+" "+str(currentdateutc)+"\n")
                offlinefile.write(offline(printername, address, currentdate))
                offcounter += 1
                counter += 1
    return counter, oncounter, offcounter
def rename():
    """Deleates old constant file and renames newconstantfile to constantfile"""
    if constantfilecheck() is True:
        os.system("del constantfile.dat")

    os.system("ren newconstantfile.dat constantfile.dat")
    os.system("del printerports.txt")

#_______________________________________________________________________________________________________________
#END OF FUNCTIONS
#_______________________________________________________________________________________________________________


oncounter=0
offcounter=0
counter=0

print ("Getting ports from server\n")   
getPorts(computername)

portslist=open("printerports.txt", "r").readlines()
newconstantfile=open("newconstantfile.dat", "w")
onlinefile=open("onlinefile.txt", "w")
offlinefile=open("offlinefile.txt", "w")

print ("checking for constant file")
if constantfilecheck() == True:
    constantfile=open("constantfile.dat").readlines()
    print("calling reader main")
    readermain(portslist, constantfile, counter, oncounter, offcounter)
    constantfile.close()
elif constantfilecheck() == False:
    print("calling reader secondary")
    readersecondary(oncounter, offcounter, counter)

offlinefile.write("\nTotal Printers Scanned: "+str(counter))
offlinefile.write("\nPrinters online: "+str(oncounter))
offlinefile.write("\nPrinters offline: "+str(offcounter))
onlinefile.write("\nTotal Printers Scanned: "+str(counter))
onlinefile.write("\nPrinters online: "+str(oncounter))
onlinefile.write("\nPrinters offline: "+str(offcounter))

portslist.close()
newconstantfile.close()
onlinefile.close()
offlinefile.close()

rename() #calls rename function

os.system を使用するべきではないことはわかっていますが、これは仕事のための迅速で汚い小さなプロジェクトになるはずでした。このプログラムは、長期間 (数年) にわたって多数のプリンター (数千台) のオンライン状態を追跡することを目的としています。これは、プリント サーバーから取得したプリンターのリストに対して ping を実行し、日付、オンライン ステータス、およびポート名を定数ファイルに記録することによって行われます。

ポートリスト ファイルの行は次のとおりです。 artp002 10.40.80.18フォーマットされた「名前ポート」

定数ファイルの例を次に示します: `artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0' 形式は「name port date_last_checked last_online_date time_in_utc」

プログラムを実行したときの出力は次のとおりです。

Getting ports from server

checking for constant file
calling reader main
artp002 10.40.80.18

artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=6ms TTL=61

Ping statistics for 10.40.80.18:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 6ms, Maximum = 6ms, Average = 6ms
artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=6ms TTL=61

Ping statistics for 10.40.80.18:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 6ms, Maximum = 6ms, Average = 6ms
artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=6ms TTL=61

print (line)これは、後の出力の一部ですfor line in portslist:

Getting ports from server

checking for constant file
calling reader main
artp002 10.40.80.18

artp002 10.40.80.18 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

['artp002', '10.40.80.18', '0', '2012-08-30', '13:32:34.787000', '2012-08-30', '13:32:34.787000', '1346347954.0']
Address found in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=8ms TTL=61

Ping statistics for 10.40.80.18:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 8ms, Maximum = 8ms, Average = 8ms
artp011 artp011.printers.xxxxxx.edu 0 2012-08-30 13:32:34.787000 2012-08-30 13:32:34.787000 1346347954.0

not in constant file

Pinging 10.40.80.18 with 32 bytes of data:
Reply from 10.40.80.18: bytes=32 time=8ms TTL=61
4

2 に答える 2

0

ファイルのすべての行を読み取ったら、を使用してカーソルを最初に巻き戻す必要がありますfile_object.seek(0)。それ以外の場合、行をさらに読み取ろうとすると、が返されNoneます。以下のコードを修正しました。最後の行を参照してください。

def readermain():
    """called if constant file exists"""

    for line in portslist: #reads printer port list and parses name and port address 
        marker = line.split()
        printername=marker[0]
        address=marker[1]

        for lines in constantfile:
            if address in lines: #if the desired address is in the line
                lineholder=lines.split()
                print (lineholder)
                oldonline=lineholder[4]
                oldutc=lineholder[5]
                status=lineholder[2]
                address=lineholder[1]

        constantfile.seek(0) # rewinds the file
于 2012-08-31T17:04:51.927 に答える
0

コードを読みやすくテストしやすくすると、問題が簡単に見つかります。具体的には:

  • 保持する変数に名前を付ける:
    • for port_info in portlines:
    • for printer_details in consntantfile:
  • 変数名の単語はアンダースコアで区切ります。
    • printer_nameではありませんprintername
    • old_utcではありませんold_utc
  • portlinesやのようなグローバル変数に依存する代わりにconstantfile、それらを引数としてこの関数に渡します。次に、小さなデータセットでこの関数を呼び出し、問題を手動でデバッグできます。
  • 2 つのファイルの内容とプログラムの出力を提供してください。
于 2012-08-31T17:22:09.203 に答える