else: syntax is incorrect - python

I am a little new to python and I am trying to write this script to cancel print jobs over 1 mb.. (the line where it is checking for size is set to 1 mb just to make sure it is working). for some reason my last else statement keeps saying it has invalid syntax. I checked to see if all parentheses were closed and I could not find an unmatched pair. could someone please tell me why it says it is invalid? Also can you take a look at my line 24 (fullname = ...grep...) to make sure the syntax on that is correct?
#! /usr/bin/python
import os
infile = open ('test.pl', 'r')
outfile = open('print.reportpython', 'w+')
newfile = infile.readlines()
newfile.pop(0)
count = 0
firstline = newfile[0]
splitline = firstline.split()
currentuser = splitline[1]
currentuser = str(currentuser)
for line in newfile:
newline = line.split()
names = newline[1]
size = int(newline[2])
names = str(names)
print names
if names is currentuser:
if size >= 1:
os.popen ("cancel lab01-10292")
fullname = os.popen("cat /etc/passwd |grep " + newline[1] + "cut -d':' -f5")
count += 1
print count
else:
print outfile.write ("(" + currentuser + ")")
print outfile.write (" ")
count = 0
currentuser = names

You do:
if foo:
bar
baz
else:
bomb
Which is wrong. All the lines between the if and its corresponding else must be indented deeper than the if and else, like this:
if foo:
bar
baz
else:
bomb

The else is at the same indentation as the previous line, but the statement on the previous line doesn't have an else clause. Fix your indentation.

Related

Pythonic way to traverse etc shadows

I am trying to implement a logic using python :
cat /etc/shadow | awk -F: '($2 == "" ) { print $1 " does not have a password "}'
If the above returns the output for the user i will do
passwd -l <username>
I am trying to implement the above logic using python , but i am not really sure if it is working out in that way; here is my python code:
/etc/shadow looks like
root:*:17709:0:99999:7:::
daemon:*:17709:0:99999:7:::
bin:*:17709:0:99999:7:::
sys:*:17709:0:99999:7:::
sync:*:17709:0:99999:7:::
games:*:17709:0:99999:7:::
man:*:17709:0:99999:7:::
lp:*:17709:0:99999:7:::
mail:*:17709:0:99999:7:::
news:*:17709:0:99999:7:::
uucp:*:17709:0:99999:7:::
proxy:*:17709:0:99999:7:::
www-data:*:17709:0:99999:7:::
backup:*:17709:0:99999:7:::
CODE
with open("/etc/shadow") as file:
for line in file:
line = line.rstrip()
if line[line.find(":")+1:line.find(":")]=="":
print "This is a problem"
elif line[line.find(":")+1:line.find(":")]=="*":
print line[line.find(":")+1:line.find(":")]
else:
print "All Good"
The above code returns "This is a problem" , which isn't right
You can use re to extract desired column:
import re
data = """root:*:17709:0:99999:7:::
daemon:*:17709:0:99999:7:::
bin:*:17709:0:99999:7:::
sys:*:17709:0:99999:7:::
sync:*:17709:0:99999:7:::
games:*:17709:0:99999:7:::
man:*:17709:0:99999:7:::
lp:*:17709:0:99999:7:::
mail:*:17709:0:99999:7:::
news:*:17709:0:99999:7:::
uucp:*:17709:0:99999:7:::
proxy:*:17709:0:99999:7:::
www-data:*:17709:0:99999:7:::
backup:*:17709:0:99999:7:::"""
groups = re.findall('(.*?):(.*?):(.*?):(.*?):(.*?):(.*?):(.*?):(.*?):', data)
if all(g[1].strip() for g in groups):
print('All good')
else:
print('This is a problem')
This prints:
All good
Explanation of this regex here. In the second group (g[1]), you have the shadowed password (*), or empty string.
Try it:
with open("/etc/shadow/") as ff:
for line in ff:
login_name,pwd,remainder=line.split(":",maxsplit=2)
print(login_name,pwd) # change it as you like
Just split your lines on the ":" separator and check the value at the second position (which is at index 1 of course):
data = """
root:*:17709:0:99999:7:::
daemon:*:17709:0:99999:7:::
bin:*:17709:0:99999:7:::
sys:*:17709:0:99999:7:::
sync:*:17709:0:99999:7:::
games:*:17709:0:99999:7:::
man:*:17709:0:99999:7:::
lp:*:17709:0:99999:7:::
mail:*:17709:0:99999:7:::
news:*:17709:0:99999:7:::
uucp:*:17709:0:99999:7:::
proxy:*:17709:0:99999:7:::
www-data:*:17709:0:99999:7:::
backup:*:17709:0:99999:7:::
"""
for line in data.strip().splitlines():
row = [part.strip() for part in line.split(":")]
if row[1] == "":
print("this is a problem")
elif row[1] == "*":
print row[1]
else:
print "all good"

Python string formatting creating a random new line on print statement

Here is my function. Trying to get this all to print to one line.
Here is the output ->
config::$var['pdf']['meta']['staff_member_name']
= ";"
The = ";" portion of the string prints to a new line in the console for some reason?
This is totally just a personal hack to help with a repetitious job requirement so i'm not looking for anything fancy.
Here is my function ->
def auto_pdf_config(file):
with open(file) as f:
content = f.readlines()
kill = " = array("
start = "config::$var['intake']"
new_line = ""
for line in content:
if kill not in line:
pass
elif start in line:
new_line = line
x = new_line.replace(kill, "")
y = x.replace(start,"")
pdf_end = ' = ";" '
z = "config::$var['pdf']['meta']{}{}".format(y,pdf_end)
print(z)
it seems you "y" variable has new line in it. you can try to strip it off.
y = x.replace(start,"").strip('\n')
Since x = new_line.replace(kill, ""), y = x.replace(start,""), and new_line is the line of content, it contains endline symbol (\n), that's why this endline symbol is appended before pdf_end. You just need to remove endline symbol from y.
You can do something like that:
y = y.strip('\n')

Evaluating the next line in a For Loop while in the current iteration

Here is what I am trying to do:
I am trying to solve an issue that has to do with wrapping in a text file.
I want to open a txt file, read a line and if the line contains what I want it to contain, check the next line to see if it does not contain what is in the first line. If it does not, add the line to the first line.
import re
stuff = open("my file")
for line in stuff:
if re.search("From ", line):
first = line
print first
if re.search('From ', handle.next()):
continue
else: first = first + handle.next()
else: continue
I have looked a quite a few things and cannot seem to find an answer. Please help!
I would try to do something like this, but this is invalid for triples of "From " and not elegant at all.
lines = open("file", 'r').readlines()
lines2 = open("file2", 'w')
counter_list=[]
last_from = 0
for counter, line in enumerate(lines):
if "From " in line and counter != last_from +1:
last_from = counter
current_count = counter
if current_count+1 == counter:
if "From " in line:
counter_list.append(current_count+1)
for counter, line in enumerate(lines):
if counter in counter_list:
lines2.write(line)
else:
lines2.write(line, '\n')
Than you can check the lines2 if its helped.
You could also revert order of lines, then check in next line not in previous. That would solve your problem in one loop.
Thank you Martjin for helping me reset my mind frame! This is what I came up with:
handle = open("my file")
first = ""
second = ""
sent = ""
for line in handle:
line = line.rstrip()
if len(first) > 0:
if line.startswith("From "):
if len(sent) > 0:
print sent
else: continue
first = line
second = ""
else:
second = second + line
else:
if line.startswith("From "):
first = line
sent = first + second
It is probably crude, but it definitely got the job done!

Python Replace String in File in With clause

I am trying to replace a string in a file.
Below code is simply modifying certain substrings within the bigger string from the file. Any ideas on how I can actually replace line with current_line in the filename?
from sys import *
import os
import re
import datetime
import fileinput
script, filename = argv
userhome = os.path.expanduser('~')
username = os.path.split(userhome)[-1]
print "\n"
print "User: " + username
today = datetime.date.today().strftime("%Y/%m/%d")
time = datetime.datetime.now().strftime("%H:%M:%S")
print "Date: " + str(today)
print "Current time: " + str(time)
print "Filename: %s\n" % filename
def replace_string():
found = False
with open(filename, 'r+') as f:
for line in f:
if re.search("CVS Header", line):
print line
####################################################################################
# Below logic: #
# if length of revision number is 4 characters (e.g. 1.15) then increment by 0.01 #
# else if it is 3 characters (e.g. 1.5) then increment by 0.1 #
####################################################################################
if len(line.split("$Revision: ")[1].split()[0]) == 4:
new_line = str.replace(line, line.split("$Revision: ")[1].split()[0], str(float(line.split("$Revision: ")[1].split()[0]) + 0.01))
elif len(line.split("$Revision: ")[1].split()[0]) == 3:
new_line = str.replace(line, line.split("$Revision: ")[1].split()[0], str(float(line.split("$Revision: ")[1].split()[0]) + 0.1))
###
###
newer_line = str.replace(new_line, line.split("$Author: ")[1].split()[0], username)
newest_line = str.replace(newer_line, line.split("$Date: ")[1].split()[0], today)
current_line = str.replace(newest_line, line.split("$Date: ")[1].split()[1], time)
print current_line
found = True
if not found:
print "No CVS Header exists in %s" % filename
if __name__ == "__main__":
replace_string()
I tried adding something like..
f.write(f.replace(line, current_line))
but this just clears all the contents out of the file and leaves it blank so obviously that is incorrect.
The fileinput provides a way to edit a file in place. If you use the inplace parameter the file is moved to a backup file and standard output is directed to the input file.
import fileinput
def clause(line):
return len(line) < 5
for line in fileinput.input('file.txt', inplace=1):
if clause(line):
print '+ ' + line[:-1]
fileinput.close()
Trying to apply this idea to your example, it could be something like this:
def replace_string():
found = False
for line in fileinput.input(filename, inplace=1): # <-
if re.search("CVS Header", line):
#print line
####################################################################################
# Below logic: #
# if length of revision number is 4 characters (e.g. 1.15) then increment by 0.01 #
# else if it is 3 characters (e.g. 1.5) then increment by 0.1 #
####################################################################################
if len(line.split("$Revision: ")[1].split()[0]) == 4:
new_line = str.replace(line, line.split("$Revision: ")[1].split()[0], str(float(line.split("$Revision: ")[1].split()[0]) + 0.01))
elif len(line.split("$Revision: ")[1].split()[0]) == 3:
new_line = str.replace(line, line.split("$Revision: ")[1].split()[0], str(float(line.split("$Revision: ")[1].split()[0]) + 0.1))
###
###
newer_line = str.replace(new_line, line.split("$Author: ")[1].split()[0], username)
newest_line = str.replace(newer_line, line.split("$Date: ")[1].split()[0], today)
current_line = str.replace(newest_line, line.split("$Date: ")[1].split()[1], time)
print current_line[:-1] # <-
found = True
else:
print line[:-1] # <- keep original line otherwise
fileinput.close() # <-
if not found:
print "No CVS Header exists in %s" % filename
The solution proposed by user2040251 is the correct way, and the way used but all text editors I know. The reason is that in case of a major problem when writing the file, you keep the previous version unmodified until the new version is ready.
But of course if you want you can edit in place, if you accept the risk of completely losing the file in case of crash - it can be acceptable for a file under version control since you can always get previous commited version.
The principle is then a read before write, ensuring that you never write something that you have not still read.
At the simplest level, you load everything in memory with readlines, replace the line rewind the file the the correct position (or to the beginning) and write it back.
Edit : here is a simple implementation when all lines can be loaded in memory :
fd = open(filename, "r+")
lines = fd.readlines()
for i, line in enumerate(lines):
# test if line if the searched line
if found :
lines[i] = replacement_line
break
fd.seek(0)
fd.writelines()
It could be done even for a big file using readlines(16384) for example instead of readlines() to read by chunks of little more than 16K, and always reading one chunk before writing previous, but it is really much more complicated and anyway you should use a backup file when processing big files.
You can create another file and write the output to it. After that, you can just remove the original file and rename the new file.

Python - searching if string is in file

I want to search for string in file and if there is string make action and if there isn´t string make other action, but from this code:
itcontains = self.textCtrl2.GetValue()
self.textCtrl.AppendText("\nTY: " + itcontains)
self.textCtrl2.Clear()
pztxtflpath = "TCM/Zoznam.txt"
linenr = 0
with open(pztxtflpath) as f:
found = False
for line in f:
if re.search("\b{0}\b".format(itcontains),line):
hisanswpath = "TCM/" + itcontains + ".txt"
hisansfl = codecs.open(hisanswpath, "r")
textline = hisansfl.readline()
linenr = 0
ans = ""
while textline <> "":
linenr += 1
textline = hisansfl.readline()
hisansfl.close()
rnd = random.randint(1, linenr) - 1
hisansfl = codecs.open(pztxtflpath, "r")
textline = hisansfl.readline()
linenr = 0
pzd = ""
while linenr <> rnd:
textline = hisansfl.readline()
linenr += 1
ans = textline
hisansfl.close()
self.textCtrl.AppendText("\nTexter: " + ans)
if not found:
self.textCtrl.AppendText("\nTexter: " + itcontains)
wrtnw = codecs.open(pztxtflpath, "a")
wrtnw.write("\n" + itcontains)
wrtnw.close
If there is not that string it is working corectly, but if there is that string, what i am searching for it makes if not found action. I really don´t know how to fix it, i have already try some codes from other sites, but in my code it doesn´t works. Can somebody help please?
Are you saying that the code underneath the following if statement executes if the string contains what you're looking for?
if re.search("\b{0}\b".format(itcontains),line):
If so, then you just need to add the following to the code block underneath this statement:
found = True
This will keep your if not found clause from running. If the string you are looking for should only be found once, I would also add a break statement to your first statement to break out of the loop.

Categories