I hope I'm not reposting (I did research before hand) but I need a little help.
So I'll explain the problem as best as I can.
I have is a text file, and inside it I have information in this format:
a 10
b 11
c 12
I read this file and convert it to a dictionary with the first column as the key, and the second as the value.
Now I'm trying to do the opposite, I need to be able to write the file back with modified values in the same format, the key separated by a space, then the corresponding value.
Why would I want to do this?
Well, all the values are supposed to be changeable by the user using the program. So when the do decide to change the values, I need them to be written back to the text file.
This is where the problem is, I just don't know how to do it.
How might I go about doing this?
I've got my current code for reading the values here:
T_Dictionary = {}
with open(r"C:\NetSendClient\files\nsed.txt",newline = "") as f:
reader = csv.reader(f, delimiter=" ")
T_Dictionary = dict(reader)
ok,supposing the dictionary is called A and the file is text.txt i would do that:
W=""
for i in A: # for each key in the dictionary
W+="{0} {1}\n".format(i,A[i]) # Append to W a dictionary key , a space , the value corresponding to that key and start a new line
with open("text.txt","w") as O:
O.write(W)
if i understood what you were asking.
however using this method would leave an empty line at the end of the file ,but that can be removed replacing
O.write(W)
with
O.write(W[0:-1])
i hope it helped
Something like this:
def txtf_exp2(xlist):
print("\n", xlist)
t = open("mytxt.txt", "w+")
# combines a list of lists into a list
ylist = []
for i in range(len(xlist)):
newstr = xlist[i][0] + "\n"
ylist.append(newstr)
newstr = str(xlist[i][1]) + "\n"
ylist.append(newstr)
t.writelines(ylist)
t.seek(0)
print(t.read())
t.close()
def txtf_exp3(xlist):
# does the same as the function above but is simpler
print("\n", xlist)
t = open("mytext.txt", "w+")
for i in range(len(xlist)):
t.write(xlist[i][0] + "\n" + str(xlist[i][1]) + "\n")
t.seek(0)
print(t.read())
t.close()
You'll have to make some changes, but it's very similar to what you're trying to do. M
Related
I am trying to lowercase the first letter after a separator or split (":"). This means that if I have a file with lines like this:
hello:world
iamlearning:python
is:cool
I would like to convert it to this:
hello:World
iamlearning:Python
is:Cool
I looked for information on how to do it, saw information and tried to do some tests, but it did not work for me. I can lower case all words, but not the first letter after a separator. Here the code:
fname = input("Enter file name: ")
f = open(fname)
s = f.read().strip().lower()
f.close()
f = open(fname,"w")
f.write(s)
f.close()
If someone can help me, I am trying to make a text editor :)
Thanks in advance.
have fun making your combo editor :^)
delimiter = ":"
with open("file.txt", "r", encoding='UTF-8')as f:
data = [f"{x}{delimiter}{y.capitalize()}" for x,y in [tuple(i.strip().split(delimiter)) for i in f.readlines()]]
with open("file.txt", "w+", encoding='UTF-8')as f: f.write("\n".join(data))
before:
username:password1
email:password2
after:
username:Password1
email:Password2
So whats going on here?
well, ets break down this crazy list comprehension
data = [tuple(i.strip().split(delimiter)) for i in f.readlines()]
which sets data to:
[('username', 'Password1'), ('email', 'Password2')]
basically a list of tuples for each combo in the combolist. ("email", "pass")
So, whats a tuple? think of it as a light ordered list of data that can easily be accessed in loops.
All this does line does is splits the data into 2 parts so i can easily edit the second in my next line. Which brings us to the second loop...
data = [f"{x}{delimiter}{y.capitalize()}" for x,y in data]
This this goes through our list of tuples data, and just joins them with an f string. you could have just as easily done (x + delimiter + (y.capitalize()))
Obviously you will want to create more modules to use in your tool so you can do the same thing while applying different things. E.g. if you wanted to add an ! to the end of a password you could edit that line and add a function in that applies to y:
import random
addSpecial(y):
return f"{y}{random.choice(["!", "?", "*", "$"])}
f"{x}{delimiter}{addSpecial(y)}"
some other resources:
Tuple unpacking in for loops
Lastly, don't use it yourself to do harm... I know a thing or two because I've seen (or done) a thing or two in that community...
Feel free to contact me via my bio for more information
Split the line, capitalize the second part, rebuild the string:
l = 'iamlearning:python'
a, b = l.split(':')
a + ':' + b.capitalize()
#'iamlearning:Python'
I am trying to join every_line in a txt file with a header text. But after successfully joining
up the lines. I cannot seem to write the file correctly as it will only write the last joined line into the internallinks.txt. How can I make it to write the whole output of combined into the file?
Any help would be appreciated, thank you very much!
Python code
with open(r"C:\Users\xingj\Desktop\writing.txt") as f:
internallink = ("www.icom.org.cn")
for every_line in f:
combined = (internallink + every_line.strip())
out_str = "".join(combined)
with open("C:\\Users\\xingj\\internallinks.txt",'w') as b:
b.write(out_str)
Content of writing.txt
/icom/faculty/viewer/?id=1122
/icom/faculty/viewer/?id=1125
/icom/faculty/viewer/?id=586&
/icom/faculty/viewer/?id=1126
/icom/faculty/viewer/?id=470&
Output of internallinks.txt
www.icom.org.cn/icom/faculty/viewer/?id=470&
Output of command print (combined) before with is closed
PS C:\Users\xingj> & python c:/Users/xingj/testingagain.py
www.icom.org.cn/icom/faculty/viewer/?id=1122
www.icom.org.cn/icom/faculty/viewer/?id=1125
www.icom.org.cn/icom/faculty/viewer/?id=586&
www.icom.org.cn/icom/faculty/viewer/?id=1126
www.icom.org.cn/icom/faculty/viewer/?id=470&
PS C:\Users\xingj>
Maybe you'd like a nested approach:
with open(r"C:\Users\xingj\Desktop\writing.txt") as f, open("C:\\Users\\xingj\\internallinks.txt",'w') as b:
for line in f:
b.write('www.icom.org.cn'+line)
In the while loop, you are re-assigning the out_str variable to the current value of combined. Instead, for your desired output, you should be appending the new value ,i.e. combined to out_str.
Just replace
for every_line in f:
combined = (internallink + every_line.strip())
out_str = "".join(combined)
with
for every_line in f:
combined = (internallink + every_line.strip())
out_str = out_str + combined
and your code should be fine.
You are assigning a new string to the combined variable you have to add the old with assigned combined to assign all of the strings
internallink = "www.icom.org.cn"
combined = ''
for every_line in tt:
# If you don't want the text on newline you can remove `\n`
combined = combined + internallink + every_line.strip() + '\n'
print(combined)
OutPut:-
www.icom.org.cn/icom/faculty/viewer/?id=1122
www.icom.org.cn/icom/faculty/viewer/?id=1125
www.icom.org.cn/icom/faculty/viewer/?id=586
www.icom.org.cn/icom/faculty/viewer/?id=1126
www.icom.org.cn/icom/faculty/viewer/?id=470
When dealing with input files, I recommend you assume the source is extremely large and code accordingly. For example, dealing with it line by line and not reading the entire file into memory:
with open(r"C:\Users\xingj\Desktop\writing.txt") as input_file:
with open(r"C:\Users\xingj\internallinks.txt", 'w') as output_file:
for link in input_file:
output_file.write('www.icom.org.cn' + link)
You can combine both open() statements into one with statement, but I see no advantage into doing so. If there is one, please comment!
I am learning Python 3 and I'm having issues completing this task. It's given a file with a string on each new line. I have to sort its content by the string located between the first hyphen and the second hyphen and write the sorted content into a different file. This is what I tried so far, but nothing gets sorted:
def sort_keys(path, input, output):
list = []
with open(path+'\\'+input, 'r') as f:
for line in f:
if line.count('-') >= 1:
list.append(line)
sorted(list, key = lambda s: s.split("-")[1])
with open(path + "\\"+ output, 'w') as o:
for line in list:
o.write(line)
sort_keys("C:\\Users\\Daniel\\Desktop", "sample.txt", "results.txt")
This is the input file: https://pastebin.com/j8r8fZP6
Question 1: What am I doing wrong with the sorting? I've used it to sort the words of a sentence on the last letter and it worked fine, but here don't know what I am doing wrong
Question 2: I feel writing the content of the input file in a list, sorting the list and writing aftwerwards that content is not very efficient. What is the "pythonic" way of doing it?
Question 3: Do you know any good exercises to learn working with files + folders in Python 3?
Kind regards
Your sorting is fine. The problem is that sorted() returns a list, rather than altering the one provided. It's also much easier to use list comprehensions to read the file:
def sort_keys(path, infile, outfile):
with open(path+'\\'+infile, 'r') as f:
inputlines = [line.strip() for line in f.readlines() if "-" in line]
outputlines = sorted(inputlines, key=lambda s: s.split("-")[1])
with open(path + "\\" + outfile, 'w') as o:
for line in outputlines:
o.write(line + "\n")
sort_keys("C:\\Users\\Daniel\\Desktop", "sample.txt", "results.txt")
I also changed a few variable names, for legibility's sake.
EDIT: I understand that there are easier ways of doing the sorting (list.sort(x)), however this way seems more readable to me.
First, your data has a couple lines without hyphens. Is that a typo? Or do you need to deal with those lines? If it is NOT a typo and those lines are supposed to be part of the data, how should they be handled?
I'm going to assume those lines are typos and ignore them for now.
Second, do you need to return the whole line? But each line is sorted by the 2nd group of characters between the hyphens? If that's the case...
first, read in the file:
f = open('./text.txt', 'r')
There are a couple ways to go from here, but let's clean up the file contents a little and make a list object:
l = [i.replace("\n","") for i in f]
This will create a list l with all the newline characters removed. This particular way of creating the list is called a list comprehension. You can do the exact same thing with the following code:
l = []
for i in f:
l.append(i.replace("\n","")
Now lets create a dictionary with the key as the 2nd group and the value as the whole line. Again, there are some lines with no hyphens, so we are going to just skip those for now with a simple try/except block:
d = {}
for i in l:
try:
d[i.split("-")[1]] = i
except IndexError:
pass
Now, here things can get slightly tricky. It depends on how you want to approach the problem. Dictionaries are inherently unsorted in python, so there is not a really good way to simply sort the dictionary. ONE way (not necessarily the BEST way) is to create a sorted list of the dictionary keys:
s = sorted([k for k, v in d.items()])
Again, I used a list comprehension here, but you can rewrite that line to do the exact same thing here:
s = []
for k, v in d.items():
s.append(k)
s = sorted(s)
Now, we can write the dictionary back to a file by iterating through the dictionary using the sorted list. To see what I mean, lets print out the dictionary one value at a time using the sorted list as the keys:
for i in s:
print(d[i])
But instead of printing, we will now append the line to a file:
o = open('./out.txt', 'a')
for i in s:
o.write(d[i] + "\n")
Depending on your system and formatting, you may or may not need the + "\n" part. Also note that you want to use 'a' and not 'w' because you are appending one line at a time and if you use 'w' your file will only be the last item of the list.
trying to find a way of making this process work pythonically or at all. Basically, I have a really long text file that is split into lines. Every x number of lines there is one that is mainly uppercase, which should roughly be the title of that particular section. Ideally, I'd want the title and everything after to go into a text file using the title as the name for the file. This would have to happen 3039 in this case as that is as many titles will be there.
My process so far is this: I created a variable that reads through a text file tells me if it's mostly uppercase.
def mostly_uppercase(text):
threshold = 0.7
isupper_bools = [character.isupper() for character in text]
isupper_ints = [int(val) for val in isupper_bools]
try:
upper_percentage = np.mean(isupper_ints)
except:
return False
if upper_percentage >= threshold:
return True
else:
return False
Afterwards, I made a counter so that I could create an index and then I combined it:
counter = 0
headline_indices = []
for line in page_text:
if mostly_uppercase(line):
print(line)
headline_indices.append(counter)
counter+=1
headlines_with_articles = []
headline_indices_expanded = [0] + headline_indices + [len(page_text)-1]
for first, second in list(zip(headline_indices_expanded, headline_indices_expanded[1:])):
article_text = (page_text[first:second])
headlines_with_articles.append(article_text)
All of that seems to be working fine as far as I can tell. But when I try to print the pieces that I want to files, all I manage to do is print the entire text into all of the txt files.
for i in range(100):
out_pathname = '/sharedfolder/temp_directory/' + 'new_file_' + str(i) + '.txt'
with open(out_pathname, 'w') as fo:
fo.write(articles_filtered[2])
Edit: This got me halfway there. Now, I just need a way of naming each file with the first line.
for i,text in enumerate(articles_filtered):
open('/sharedfolder/temp_directory' + str(i + 1) + '.txt', 'w').write(str(text))
One conventional way of processing a single input file involves using a Python with statement and a for loop, in the following way. I have also adapted a good answer from someone else for counting uppercase characters, to get the fraction you need.
def mostly_upper(text):
threshold = 0.7
## adapted from https://stackoverflow.com/a/18129868/131187
upper_count = sum(1 for c in text if c.isupper())
return upper_count/len(text) >= threshold
first = True
out_file = None
with open('some_uppers.txt') as some_uppers:
for line in some_uppers:
line = line.rstrip()
if first or mostly_upper(line):
first = False
if out_file: out_file.close()
out_file = open(line+'.txt', 'w')
print(line, file=out_file)
out_file.close()
In the loop, we read each line, asking whether it's mostly uppercase. If it is we close the file that was being used for the previous collection of lines and open a new file for the next collection, using the contents of the current line as a title.
I allow for the possibility that the first line might not be a title. In this case the code creates a file with the contents of the first line as its names, and proceeds to write everything it finds to that file until it does find a title line.
I am currently keeping high scores into a text file called "score.txt". The prgoram works fine, updating the file with the new high scores as normal. Except that every time the program updates the file, there is always one blank line before the first high score, creating an error when I try to save the scores the next time. The code:
scores_list = []
score = 10
def take_score():
# Save old scores into list
f = open("score.txt", "r")
lines = f.readlines()
for line in lines:
scores_list.append(line)
print scores_list
f.close()
take_score()
def save_score():
# Clear file
f = open("score.txt", "w")
print >> f, ""
f.close()
# Rewrite scores into text files
w = open("score.txt", "a")
for i in range(0, len(scores_list)):
new_string = scores_list[i].replace("\n", "")
scores_list[i] = int(new_string)
if score > scores_list[i]:
scores_list[i] = score
for p in range(0, len(scores_list)):
print >> w, str(scores_list[p])
print repr(str(scores_list[p]))
save_score()
The problem mentioned happens in the save_score() function. I have tried this related question: Removing spaces and empty lines from a file Using Python, but it requires I open the file in "r" mode. Is there a way to accomplish the same thing except when the file is opened in "a" mode (append)?
You are specifically printing an empty line as soon as you create the file.
print >> f, ""
You then append to it, keeping the empty line.
If you just want to clear the contents every time you run this, get rid of this:
# Clear file
f = open("score.txt", "w")
print >> f, ""
f.close()
And modify the opening to this:
w = open("score.txt", "w")
The 'w' mode truncates already, as you were already using. There's no need to truncate, write an empty line, close, then append lines. Just truncate and write what you want to write.
That said, you should use the with construct and file methods for working with files:
with open("score.txt", "w") as output: # here's the with construct
for i in xrange(len(scores_list)):
# int() can handle leading/trailing whitespace
scores_list[i] = int(scores_list[i])
if score > scores_list[i]:
scores_list[i] = score
for p in xrange(len(scores_list)):
output.write(str(scores_list[p]) + '\n') # writing to the file
print repr(str(scores_list[p]))
You will then not need to explicitly close() the file handle, as with takes care of that automatically and more reliably. Also note that you can simply send a single argument to range and it will iterate from 0, inclusive, until that argument, exclusive, so I've removed the redundant starting argument, 0. I've also changed range to the more efficient xrange, as range would only be reasonably useful here if you wanted compatibility with Python 3, and you're using Python 2-style print statements anyway, so there isn't much point.
print appends a newline to what you print. In the line
print >> f, ""
You're writing a newline to the file. This newline still exists when you reopen in append mode.
As #Zizouz212 mentions, you don't need to do all this. Just open in write mode, which'll truncate the file, then write what you need.
Your opening a file, clearing it, but then you open the same file again unnecessarily. When you open the file, you print a newline, even if you don't think so. Here is the offending line:
print >> f, ""
In Python 2, it really does this.
print "" + "\n"
This is because Python adds a newline at the end of the string to each print statement. To stop this, you could add a comma to the end of the statement:
print "",
Or just write directly:
f.write("my data")
However, if you're trying to save a Python data type, and it does not have to be human-readable, you may have luck using pickle. It's really simple to use:
def save_score():
with open('scores.txt', 'w') as f:
pickle.dump(score_data, f):
It is not really answer for question.
It is my version of your code (not tested). And don't avoid rewriting everything ;)
# --- functions ---
def take_score():
'''read values and convert to int'''
scores = []
with open("score.txt", "r") as f
for line in f:
value = int(line.strip())
scores.append(value)
return scores
def save_score(scores):
'''save values'''
with open("score.txt", "w") as f
for value in scores:
write(value)
write("\n")
def check_scores(scores, min_value):
results = []
for value in scores:
if value < min_value:
value = min_value
results.append(value)
return resulst
# --- main ---
score = 10
scores_list = take_score()
scores_list = check_scores(scores_list, score)
save_score(scores_list)