How to capture the string in function.py and track the def step1() and its following function create() and login() into dictionary format? (The format i want to achieve is below)
function.py
#!C:\Python\Python39\python.exe
# print ('Content-type: text/html\n\n')
def step1():
create()
login()
def step2():
authenticate()
def step3():
send()
Expected output
thisdict = {
'def step1()': ['create(),login()'],
'def step2():':['authenticate()'],
'def step3():': ['send()']
}
You can read the file function.py, split it in order to separate the different functions, and then for each function, split it once more to get the signature as key and the commands as values:
with open('function.py', 'r') as inFile:
funcs = inFile.read().split('\n\n')[1:]
result = {}
for elem in funcs:
sign, commands = elem.split(':')
commands = list(map(str.strip, commands.split('\n')))[1:]
result.update({sign : commands})
print(result)
This will return:
{'def step1()': ['create()', 'login()'], 'def step2()': ['authenticate()'], 'def step3()': ['send()']}
You could use a regex that would find each method and content (def \w+\(.*\):)((?:\n[ \t]+.+)+)
(def \w+\(.*\):) for the method definition
\n[ \t]+.+ for each method row (with the previous \n)
import json
import re
with open("function.py") as fic:
content = fic.read()
groups = re.findall(r"(def \w+\(.*\):)((?:\n[ \t]+.+)+)", content)
result = {key: [",".join(map(str.strip, val.strip().splitlines()))]
for key, val in groups}
print(json.dumps(result, indent=4))
you can do something like that:
with open('function.py', 'r') as f:
file = f.readlines()
thisdict = {'start':[]}
temp = []
a = '_start_' #just to get the first lines if there is some things before the first function
for line in file:
if line.startsWith('def'): #You might want to add something for the spacing
thisdict[a] = temp
a = line[3:]
temp=[]
else:
temp.append(line)
thisdict[a] = temp
print(thisdict)
this clearly isn't the best code but it's easy to understand and easy to implement :)
Related
This is what I have so far, right now I get sankey is not defined.
def makeSankey (inf):
sankey = {}
with open("file.txt") as f:
for line in f:
(key, val) = line.split()
sankey[str(key)] = val
return makeSankey()
for i in sankey():
print(i),sankey[i]`
The text file looks like this:
Single,2106
Double,603
Triple,44
Home Run,431
Walk / HBP,1402
Sacrifice Out,137
Other Out,8160
First of all, you can't access sankey outside the function.
You can't call sankey as it's not your function's name which is makeSankey.
What you meant to do with return makeSankey was probably return the value, which is stored in sankey so you return sankey.
Your code in fixed condition should be something like this, I still am not sure about the input if it's the same as you provided but you can try it:
def makeSankey(fileName):
sankey = {}
with open(fileName) as f:
for line in f:
(key, val) = line.split()
sankey[key] = val
return sankey
data = makeSankey("file.txt")
for i in data:
print(i, data[i])
This works if file.txt contains lines like key,val. use python script.py file.txt
#!/usr/bin/python2
import sys
def makeSankey(file_name):
sankey = {}
with open(file_name) as f:
for line in f:
(key,val) = line.split(",")
# strip to remove \n
sankey[key] = val.strip()
# return the dic to the caller
return sankey
if __name__ == "__main__":
# received file name as an argument, if not then just pass it to makeSankey fun
sanKeyDic = makeSankey(sys.argv[1])
print(sanKeyDic)
I want to pass dictionary to user defined functions and I need to do some calculation based on the dictionary values. It is not working for me with functions but works fine without using functions. I am not sure, what is wrong with code. Any help please? No error message.
Input:
"13-07-2016 12:55:46",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 12:57:50",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 13:00:43",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 13:01:45",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 13:02:57",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 13:04:59",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 13:06:51",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
"13-07-2016 13:07:56",user,192.168.10.100,192.168.10.20,CONNECT,200,"www.abc.com"
Code:
file_name = sys.argv[1]
fo = open(file_name, "rb")
def setdict():
dico,i={},0
line = fo.readline()
for line in fo:
date, user, proxy_ip, client_ip, access_method, con, sites = line.split(",")
sites = sites.rstrip('\n')
dico[i]= date, user, proxy_ip, client_ip, access_method, con, sites
return dico
def display(dico):
for k,v in dico.items():
print k,v
A: You should consider to call your functions at the end of the script:
dico = setdict()
display(dico)
Without that, they are declared, but not used.
B: You should also consider a better way to open your file:
with open(file_name, "rb") as f:
lines = f.readlines()
for line in lines:
# Do stuff with your line
This is the best way to open a file in python and to read it line by line.
C: You are using:
line = fo.readline()
# ^ That line is never use after, you will loose all it's datas
for line in fo:
#do stuff on line
I've add a comment to show you that you loose the data from the first line.
D: You are using global variable (you use fo inside setdict() a better way will be to pass it by arguments:
fo = open(file_name, "rb")
def setdict(fo):
dico,i={},0
line = fo.readline()
...
setdict(fo)
Finally, here is how you can rewrite your script :
def setdict(filename):
dico,i={},0
with open(filename, 'r') as f:
for line in f.readlines():
date, user, proxy_ip, client_ip, access_method, con, sites = line.split(",")
sites = sites.rstrip('\n')
dico[i]= date, user, proxy_ip, client_ip, access_method, con, sites
return dico
def display(dico):
for k,v in dico.items():
print k,v
file_name = sys.argv[1]
dico = setdict(filename)
display(dico)
When you write a function in Python using the def keyword, the function is not automatically executed. You are never calling your setdict or display functions, just defining them so they can be called later.
Add this line to the end of your script to actually call the functions you defined:
display(setdict())
or more verbosely
dico = setdict()
display(dico)
I do have following code where I am its doing following thing.
Parsing Whole file and checking for patter in each line. If the pattern exists, it should return that pattern to main function and print the value.
Issue: The function is only returning 1st pattern and do not check for same pattern into multiple lines.
code:
import re
import sys
import os
def find_pattern(file):
with open(file) as fp:
for line in fp:
if "abc" in line:
return line
else:
continue
def check(file):
return_list = []
data=find_pattern(file)
if data != None:
return_list.append(data)
if not data:
return "working"
else:
return return_list
if __name__== '__main__':
file = sys.argv[1]
print check(file)
If the file has multiple line containing abc, it will print only 1st line and skip other lines. I want to print all lines that contains abc.
Sample file
sdfdsffdabcafsfse
asasssadfsdadsadsaddsadadabc
asfasfdsafdfabc
output with above code:
sdfdsffdabcafsfse
You are prematurely returning from the function on this line:
return line
Which means you exit the function and the loop ceases to iterate assoon as the first instance is found.
Consider something like this instead, where you capture and return all matches:
def find_pattern(file):
out = []
with open(file) as fp:
for line in fp:
if "abc" in line:
out.append(line)
else:
continue
return out
Alternatively, you can manage this in a single, simple list comprehension:
def find_pattern(file):
with open(file) as fp:
return [line for line in fp if "abc" in line]
I have a pre-formatted text file with some variables in it, like this:
header one
name = "this is my name"
last_name = "this is my last name"
addr = "somewhere"
addr_no = 35
header
header two
first_var = 1.002E-3
second_var = -2.002E-8
header
As you can see, each score starts with the string header followed by the name of the scope (one, two, etc.).
I can't figure out how to programmatically parse those options using Python so that they would be accesible to my script in this manner:
one.name = "this is my name"
one.last_name = "this is my last name"
two.first_var = 1.002E-3
Can anyone point me to a tutorial or a library or to a specific part of the docs that would help me achieve my goal?
I'd parse that with a generator, yielding sections as you parse the file. ast.literal_eval() takes care of interpreting the value as a Python literal:
import ast
def load_sections(filename):
with open(filename, 'r') as infile:
for line in infile:
if not line.startswith('header'):
continue # skip to the next line until we find a header
sectionname = line.split(None, 1)[-1].strip()
section = {}
for line in infile:
if line.startswith('header'):
break # end of section
line = line.strip()
key, value = line.split(' = ', 1)
section[key] = ast.literal_eval(value)
yield sectionname, section
Loop over the above function to receive (name, section_dict) tuples:
for name, section in load_sections(somefilename):
print name, section
For your sample input data, that results in:
>>> for name, section in load_sections('/tmp/example'):
... print name, section
...
one {'last_name': 'this is my last name', 'name': 'this is my name', 'addr_no': 35, 'addr': 'somewhere'}
two {'first_var': 0.001002, 'second_var': -2.002e-08}
Martijn Pieters is correct in his answer given your preformatted file, but if you can format the file in a different way in the first place, you will avoid a lot of potential bugs. If I were you, I would look into getting the file formatted as JSON (or XML), because then you would be able to use python's json (or XML) libraries to do the work for you. http://docs.python.org/2/library/json.html . Unless you're working with really bad legacy code or a system that you don't have access to, you should be able to go into the code that spits out the file in the first place and make it give you a better file.
def get_section(f):
section=[]
for line in f:
section += [ line.strip("\n ") ]
if section[-1] == 'header': break
return section
sections = dict()
with open('input') as f:
while True:
section = get_section(f)
if not section: break
section_dict = dict()
section_dict['sname'] = section[0].split()[1]
for param in section[1:-2]:
k,v = [ x.strip() for x in param.split('=')]
section_dict[k] = v
sections[section_dict['sname']] = section_dict
print sections['one']['name']
You can also access these sections as attributes:
class Section:
def __init__(self, d):
self.__dict__ = d
one = Section(sections['one'])
print one.name
I've a file entitled 'users.txt' with the following structure; username:info_about_the_user.
Something like this:
users.txt:
mark:stuffabouthim anthony:stuffabouthim peter:stuffabouthim peterpeter:stuffabouthim peterpeterpeter:stuffabouthim peterpeterpeterpeter:stuffabouthim
The following part of the script needs to change a line (change info about an user) but I'm having problems when the string is duplicated (peter - peterpeter) and I dont know how to fix it.
def test():
fn = 'users.txt'
f = open(fn)
output = []
changeuser = 'peterpeter'
userinfo = 'HeIsTall'
for line in f:
if not changeuser+":" in line:
output.append(line)
f.close()
f = open(fn, 'w')
f.writelines(output)
f.close()
f = open("users.txt", "a")
f.write(changeuser + ":" + userinfo+"\n")
f = open("users.txt", "a")
test()
This is the input I have:
Input: users.txt:
mark:stuffabouthim anthony:stuffabouthim peter:stuffabouthim peterpeter:HesAwesome peterpeterpeter:stuffabouthim peterpeterpeterpeter:stuffabouthim
I want to change info about peterpeter and have the following output:
Output I want to have: users.txt:
mark:stuffabouthim anthony:stuff about him peter:stuffabouthim peterpeter:HeIsTall peterpeterpeter:stuffabouthim peterpeterpeterpeter:stuffabouthim
But this is the input I'm having. All the lines behind peterpeter are getting deleted among other things.
mark:stuffabouthim
anthony:stuffabouthim
peter:stuffabouthim
peterpeter:HeIsTall
Can anyone give me a help with the code below to have the desired output? Thanks.
You can have it the easy way with the fileinput module:
import fileinput
def test():
fn = 'users.txt'
changeuser = 'peterpeter'
newinfo = 'HeIsTall'
for line in fileinput.input(fn, inplace=1):
user, oldinfo = line.split(':')
print '%s:%s' % (user, newinfo if user == changeuser else oldinfo.replace('\n', ''))
if __name__ == "__main__":
test()
try this:
def test():
fn = 'users.txt.txt'
f = open(fn)
output = []
changeuser = 'peterpeter'
userinfo = 'HeIsTall'
for line in f:
if line.strip().split(':')[0]!=changeuser:
output.append(line)
else:
output.append(changeuser + ":" + userinfo+"\n")
f.close()
f = open(fn, 'w')
f.writelines(output)
f.close()
test()
output:
mark:stuffabouthim
anthony:stuffabouthim
peter:stuffabouthim
peterpeter:HeIsTall
peterpeterpeter:stuffabouthim
peterpeterpeterpeter:stuffabouthim
You got a logical error in the if-clause, which DELETES all peters*, the only peter remaining is the one you append to the file.
for line in f:
if not changeuser+":" in line: #THAT MEANS ALL PETERS ARE IGNORED!
output.append(line)
It's generaly easier to understand positive clauses then a negation:
for line in f:
if changeuser+":" in line:
output.append('%s:%s\n' %(changeuser,userinfo))
else:
output.append(line)
Good code is easy to read. Try to code like you would try to write a report! That leads automatically to spliting your code into smaller pieces like functions. e.g.:
lines = read_all_lines_from_file(filename)
change_user_info(lines, user, userinfo)
save_lines_to_file(lines, filename)
Your code gets split into smaller pieces and if an error occurs you can pin it down to a few lines of code instead of having to work over several pages. ;-)