How do I handle the ',' in the sys.argv __name__ statement below - python

This is a little terminal journal app I am working on.
Intended functionality: type in terminal python3 journal.py whatever note I want to keep, with commas included. The entry 'whatever note I want to keep, with commas included' gets stored in a csv in a single cell.
Actual functionality: the note 'whatever note I want to keep, with commas included' is split into multiple cells on the ','. This problem was solved in the multi_stuff function but the same technique isn't working in the sys.argv[1:] in the name portion.
any thoughts?
import csv
import sys
import re
import datetime
def record(stuff):
with open('journal.csv', 'a') as f:
f.write(str(datetime.datetime.now())+','+stuff+'\n')
def multi_line():
while True:
multi_stuff = input('Type "Q" to quit. Otherwise, talk to me -> ').lower()
if ',' in multi_stuff:
multi_stuff = multi_stuff.replace(',', '","')
if multi_stuff == 'q':
break
with open('journal.csv', 'a') as f:
f.write(str(datetime.datetime.now())+','+multi_stuff+'\n')
def search():
keyword = input('search term -> ').lower()
regex = r"\b(?=\w)" + re.escape(keyword) + r"\b(?!\w)"
with open('journal.csv', 'r') as csv:
for line in csv:
if re.search(regex, line):
print(line)
if __name__ == '__main__':
if sys.argv[1].lower() == '-s':
search()
elif sys.argv[1].lower() == '-m':
multi_line()
else:
arg = sys.argv[1:]
if ',' in arg:
arg = arg.replace(',', '","')
record(' '.join(arg))
else:
record(' '.join(arg))

Related

So i wrote a script and i need to fix it so it doesnt write in the script in string form, see the problem in its body

PyPython.py
from Project import *
v = open("Project.py", "w")
w = open("Backup.txt", "w")
PInput = None
DisableCode = "Save"
LineSeek = 0
Line = "None"
while PInput != DisableCode:
PInput = input(": ")
if PInput == "Create Line":
Line = input("Type in the command: ")
Line = repr(Line)
v.write(Line + "\n")
w.write(Line + "\n")
print("Done!")
After running the code
in Project.py...
'print("Hi")'
It must be
print("Hi")
What should i do change in PyPython.py to get rid of string marks in Project.py?
There is no need for repr(Line) here. The repr() method returns a string containing a printable representation of an object.
Try removing that line, it will work as expected.

Saving formatted data separated by vertical bars(pipe-delimited) to a file in Python

# Get the filepath from the command line
import sys
F1= sys.argv[1]
F2= sys.argv[2]
"""load the two files for processing"""
action_log=[]
#open first file
with open(F1, 'r') as accounts_file:
main_log = accounts_file.read().splitlines()
split_main_log = [word.split('|') for word in main_log]
#open second file
with open(F2, 'r') as command_file:
command_log = command_file.read().splitlines()
split_command_file = [word.split('|') for word in command_log]
for i in range(0, len(split_command_file)):
if (split_main_log[i][1] == split_command_file[i][3] and split_command_file[i][0] == 'sub'):
if split_main_log[i][2] >= split_command_file[i][1]:
split_main_log[i][2] = int(split_main_log[i][2]) - int(split_command_file[i][1])
elif split_main_log[i][1] == split_command_file[i][3] and split_command_file[i][0] == 'add':
split_main_log[i][2] = int(split_main_log[i][2]) + int(split_command_file[i][1])
for i in range(0,len(split_main_log)):
split_main_log[i] = str(split_main_log[i])
for i in range(0,len(split_main_log)):
split_main_log[i]='|'.join(split_main_log[i])
output_new = ""
output_new = "\n".join(split_main_log)
out_file = open(F1,'w') #openfile
out_file.write(output_new)
I am unsure of why my output has so many vertical bars. I'm just overlooking something and need another eye on it (been at it for a few hours). Any help would be awesome.
How about using csv? and simply telling csv writer to use pipe sign as delimiter?
import csv
with open("test.csv", "w", newline='') as csv_file:
csv_writer = csv.writer(csv_file, delimiter='|')
csv_writer.writerow(["ColumnName1", "ColumnName2", "ColumnName3"])
for i in listOfDictionary:
csv_writer.writerow([i["key1"], i["key2"], i["key3"]])
The code inserts | between each character because it passes a str as an argument to join. The str.join method takes a sequence as an argument and returns a str which is each element of the sequence separated by the instance which called join. You may demonstrate this for yourself by running '|'.join('foobarbaz').
You can start by removing this cast to str:
for i in range(0,len(split_main_log)):
split_main_log[i] = str(split_main_log[i])
This will likely break the str.join call since you're casting the values to int in the parent for loop. You'll need to cast those values to str after you're done with the arithmetic, like this:
for i in range(0, len(split_command_file)):
if (split_main_log[i][1] == split_command_file[i][3] and split_command_file[i][0] == 'sub'):
if split_main_log[i][2] >= split_command_file[i][1]:
split_main_log[i][2] = str(int(split_main_log[i][2]) - int(split_command_file[i][1]))
elif split_main_log[i][1] == split_command_file[i][3] and split_command_file[i][0] == 'add':
split_main_log[i][2] = str(int(split_main_log[i][2]) + int(split_command_file[i][1]))
Please provide a minimum reproducible sample and I can help more. It's difficult to debug this without the input files.

Why does this cycle make an empty row after checking one row?

This program is supposed to replace the letters ö,ä,õ,ü with different letters. After completing one row it produces an empty row and I don't know why. I have tried to understand it for some time, but I couldn't really understand why it doesn't give me desired output.
f = input("Enter file name: ")
file = open(f, encoding="UTF-8")
for sentence in file:
sentence = sentence.upper()
for letter in sentence:
if letter == "Ä":
lause = sentence.replace(letter, "AE")
elif letter == "Ö" or täht == "Õ":
lause = sentence.replace(letter, "OE")
elif letter == "Ü":
lause = sentence.replace(letter, "UE")
print(sentence)
Reading each line in includes the trailing newline. Your print() also includes a newline so you will get an empty row. Try print(sentence, end='') as follows:
filename = input("Enter file name: ")
with open(filename, encoding="UTF-8") as f_input:
for sentence in f_input:
sentence = sentence.upper()
for letter in sentence:
if letter == "Ä":
lause = sentence.replace(letter, "AE")
elif letter == "Ö" or täht == "Õ":
lause = sentence.replace(letter, "OE")
elif letter == "Ü":
lause = sentence.replace(letter, "UE")
print(sentence, end='')
Note: using with open(... will also automatically close your file afterwards.
You might also want to consider the following approach:
# -*- coding: utf-8
filename = input("Enter file name: ")
replacements = [('Ä', 'AE'), ('ä', 'ae'), ('Ö', 'OE'), ('ö', 'oe'), ('Õ', 'OE'), ('õ', 'oe'), ('Ü', 'UE'), ('ü', 'ue')]
with open(filename, encoding='utf-8') as f_input:
text = f_input.read()
for from_text, to_text in replacements:
text = text.replace(from_text, to_text)
print(text)
This does each replacement on the whole text rather than line by line. It also preserves the case.
I won't fix your program, just try to answer why it doesn't do what you are expecting:
The program doesn't run: in line 14 the variable "täht" might be a typo, supposed to be "letter"
You store the result of replace() in variable "lause" but never use it
by default print() adds "\n" at the end, but you can override it (see help(print) in the python shell)

Python string compare and replace

I have a .txt with:
#Date 111111:UhUidsiIds
#Name Sebastian-Forset
#Date 222222:UdfasdUDsa
#Name Sebastian_Forset2
#Date 333333:UDsafduD
#Name Solaris Mage
#Date 444444:Ghdsasra
#Name Marge S
and a file whith:
#Name Sebastian Forset
#Date 191020
#Name Sebastian Forset2
#Date 201020
#Date Homer S
#Date 281902
The names are the same, with some differences of characters (spaces, -, _ etc.)
I would copy the numbers of the second file to the first file in order to have a final file txt with:
#Name Sebastian Forset
#Date 191020:UhUidsiIds
#Name Sebastian Forset2
#Date 201020:UdfasdUDsa
#Name Solaris Mage
#Date 281902:UDsafduD
#Name Marge S
#Date 444444:Ghdsasra
This is my code, but merge the file, copy only same name
def isInFile(l, f):
with open(f, 'r') as f2:
for line in f2:
if l == line:
return True
return False
def similitudes(file1, file2):
same = 0
data = ''
copy = False
with open(file1, 'r') as f1:
for line in f1:
if copy == True:
data += line
if line == '\n' or line[0:6] != '#Name ':
copy = False
if (line[0:6] == '#Name ') or line[0:6] == '#Date ':
print line
if isInFile(line, file2) == True:
copy = True
data += line
print "true"
else:
print "ok"
same += 1
return data
def main(argv=2):
print (sys.argv[1])
print (sys.argv[2])
if argv == 2:
out = open('final.txt', 'w')
data = (
similitudes(sys.argv[1], sys.argv[2]) + '\n'
)
out.write(data)
out.close()
else:
print ("This program need 2 files")
exit (0)
return 0
if __name__ == '__main__':
status = main()
sys.exit(status)
First, list out the characters that will differ. Let's say "-" , "_" and " ".
Now split the two strings using these delimiters. you can use "re" package in python.
>>> a='Mr-Sebastian_Forset '
>>> import re
>>> re.split('- |_ | ',a)
['Mr', 'Sebastian', 'Forset']
If the resultant lists for the two strings are equal, paste the number in second file in first one.
You can use the same delimiter concept to split the number and paste it in other file.
Adding another answer, which will points out the bug in your code
Coming to the following piece of code
if (line[0:6] == '#Name ') or line[0:6] == '#Date ':
print line
if isInFile(line, file2) == True:
copy = True
data += line
Here, you are checking If your line starts with either "#Name " or "#Date ", and calling isInFile() method with line and file2 as arguments.
This is the first issue, there is no use of sending just one line that starts with "#Name " in your case.
If the current line starts with "#Date ", send the previous line and file as arguments to this method.
And second Issue is with the isInFile() definition, which is doing effectively nothing.
if l == line:
return true
You are just checking if two lines in file1 and file2 are same and if yes, you writing this line in sysout.
So, your program will just print the common lines between file1 and file2.
Modified code should like the below one:
def isInFile(l, f):
line_found = false
required_line = null
with open(f, 'r') as f2:
for line in f2:
if line_found:
required_line = line
break
elif l == line:
line_found = true
return (line_found, required_line)
def similitudes(file1, file2):
same = 0
data = ''
copy = False
previous_line = null
with open(file1, 'r') as f1:
for line in f1:
if copy == True:
data += line
if line == '\n' or line[0:6] != '#Name ':
copy = False
if (line[0:6] == '#Name '):
print line
previous_line = line
elif line[0:6] == '#Date ':
print line
file2_line_info = isInFile(previous_line, file2)
if file2_line_info[0] == True:
copy = True
data += file2_line_info[1]
print "true"
return data
def main(argv=2):
print (sys.argv[1])
print (sys.argv[2])
if argv == 2:
out = open('final.txt', 'w')
data = (
similitudes(sys.argv[1], sys.argv[2]) + '\n'
)
out.write(data)
out.close()
else:
print ("This program need 2 files")
exit (0)
return 0
if __name__ == '__main__':
status = main()
sys.exit(status)
Note: This is not the pythonic way of doing things. As I have mentioned in the above answer https://stackoverflow.com/a/34696778/3534696 use "re" module and solve the problem efficiently.
Read the first file into a dictionary, using maketrans/translate to clean up the name.
Using zip(file, file) to read 2 lines of the file at a time makes it much easier to handle.
And using .split(' ', 1)[1] to get rid of the first column.
And .strip() to get rid of any surrounding whitespace (i.e. \n)
Then you can read the second file updating the dictionary.
In Python3 this looks like:
>>> punc = str.maketrans('_-', ' ') # import string & string.maketrans() in Py2
>>> with open(filename1) as file1, open(filename2) as file2:
... data = {name.split(' ', 1)[1].strip().translate(punc):
... date.split(' ', 1)[1].strip().split(':')
... for name, date in zip(file1, file1)}
... for n, d in zip(file2, file2):
... data[n.split(' ', 1)[1].strip()][0] = d.split(' ', 1)[1].strip()
>>> data
{'Marge S': ['444444', 'Ghdsasra'],
'Sebastian Forset': ['191020', 'UhUidsiIds'],
'Sebastian Forset2': ['201020', 'UdfasdUDsa'],
'Solaris Mage': ['281902', 'UDsafduD']}
After that it is just a matter of writing the dictionary out to a new file.
>>> with open(<output>, 'w+') as output:
... for name, date in data.items():
... output.write('#Name {}\n'.format(name))
... output.write('#Date {}:{}\n'.format(*date))
Note: I had to change 'Homer S' to 'Solaris Mage' in the second file to get the stated output.

Remove duplicates after altering items

I have a script to clean urls to get base domains from example.com/example1 and example.com/example2 down to example.com My issue is when it goes to through the file of urls it will have duplicate base domains. I want to remove the duplicates while printing the urls to a file. below is the code I currently have.
enter from Tkinter import *
import tkFileDialog
import re
def main():
fileOpen = Tk()
fileOpen.withdraw() #hiding tkinter window
file_path = tkFileDialog.askopenfilename(
title="Open file", filetypes=[("txt file",".txt")])
if file_path != "":
print "you chose file with path:", file_path
else:
print "you didn't open anything!"
fin = open(file_path)
fout = open("URL Cleaned.txt", "wt")
for line in fin.readlines():
editor = (line.replace('[.]', '.')
.replace('[dot]', '.')
.replace('hxxp://www.', '')
.replace('hxxps://www.', '')
.replace('hxxps://', '')
.replace('hxxp://', '')
.replace('www.', '')
.replace('http://www.', '')
.replace('https://www.', '')
.replace('https://', '')
.replace('http://', ''))
editor = re.sub(r'/.*', '', editor)
if __name__ == '__main__':
main()
Any help is appreciated. I have scoured the posts and tried all of the suggestions for my issue and have not found one that works.
You can use regular expresion to find the base domains.
If you have one url per line in your file:
import re
def main():
file = open("url.txt",'r')
domains = set()
# will works for any web like https://www.domain.com/something/somethingmore... , also without www, without https or just for www.domain.org
matcher= re.compile("(h..ps?://)?(?P<domain>(www\.)?[^/]*)/?.*")
for line in file:
# make here any replace you need with obfuscated urls like: line = line.replace('[.]','.')
if line[-1] == '\n': # remove "\n" from end of line if present
line = line[0:-1]
match = matcher.search(line)
if match != None: # If a url has been found
domains.add(match.group('domain'))
print domains
file.close()
main()
For example, with this file, it will print:
set(['platinum-shakers.net', 'wmi.ns01.us', 'adservice.no-ip.org', 'samczeruno.pl', 'java.ns1.name', 'microsoft.dhcp.biz', 'ids.us01.us', 'devsite.quostar.com', 'orlandmart.com'])
perhaps you could use a regular expression:
import re
p = re.compile(r".*\.com/(.*)") # to get for instance 'example1' or 'example2' etc.
with open(file_path) as fin, open("URL Cleaned.txt", "wt") as fout:
lines = fin.readlines():
bases = set(re.search(p, line).groups()[0] for line in lines if len(line) > 1)
for b in bases:
fout.write(b)
Using with open(..) auto closes the files after the executing the block of code
Output:
Using a text file with:
www.example.com/example1
www.example.com/example2
# blank lines are accounted for
www.example.com/example3
www.example.com/example4
www.example.com/example4 # as are duplicates
as the lines, I got the output,
example1
example2
example3
example4

Categories

Resources