How can I raise in python specific ValueError? - python

I have to raise ValueError('Invalid file name') if my infile or outfile or the two of them is empty
this is the code in python:
def get_x_freqs(infile, outfile, x):
# Write the rest of the code for question 3 below here.
f =None
try:
f=open(infile, "r")
if infile=='':
raise ValueError('Invalid file name')
else:
d={}
for line in f:
element = line.split()
for word in element:
d[word]=d.get(word,0)+1
try:
f=open(outfile, "w")
if outfile=='':
raise ValueError('Invalid file name')
else:
sorted_elements = sorted(d.keys(), key=d.get, reverse=True)
for e in sorted_elements[:x]:
print(e, ':', d[e])
finally:
if f!= None:
f.close()
in_filename = 'C:\\Users\\shirl\\Desktop\\מדעים להייטק\\פיתון\\Exercises\\ex.5\\q3.txt'
out_filename = 'C:\\Users\\shirl\\Desktop\\מדעים להייטק\\פיתון\\Exercises\\ex.5\\q3_out.txt'
get_x_freqs(in_filename, out_filename, 3)

Your try-except blocks should more look like this:
try:
f=open(infile, "r")
d = {}
for line in f:
element = line.split()
for word in element:
d[word] = d.get(word, 0) + 1
except:
raise ValueError('Invalid file name')

Related

Removing lines that have strings with same hexadecimal values from a text file

I have a file in1.txt
info="0x0000b573" data="0x7" id="sp. PCU(Si)"
info="0x0000b573" data="0x00000007" id="HI all. SHa"
info="0x00010AC3" data="0x00000003" id="abc_16. PS"
info="0x00010ac3" data="0x00000045" id="hB2_RC/BS (Spr)"
info="0x205" data="0x00000010" id="cgc_15. PK"
info="0x205" data="0x10" id="cgsd_GH/BS (Scd)"
Expected output: out.txt
info="0x00010AC3" data="0x00000003" id="abc_16. PS"
info="0x00010ac3" data="0x00000045" id="hB2_RC/BS (Spr)"
I need only lines that have same info values and different data values to be written to out.txt.
but the current code removes all the line that have string data in it.
with open("in.txt", "r") as fin,open("out.txt", "w") as fout:
for line in fin:
if 'data' not in line:
fout.write(line.strip()+'\n')
what i need is for eg: line 1 and line 2 is having same info="0x0000b573" and data is "0x7" & "0x00000007" which is same then remove that line.
You can use regex
import re
s = '''info="0x0000b573" data="0x7" id="sp. PCU(Si)"
info="0x0000b573" data="0x00000007" id="HI all. SHa"
info="0x00010AC3" data="0x00000003" id="abc_16. PS"
info="0x00010ac3" data="0x00000045" id="hB2_RC/BS (Spr)"
info="0x205" data="0x00000010" id="cgc_15. PK"
info="0x205" data="0x10" id="cgsd_GH/BS (Scd)"'''
parsed_data = re.findall(r'info="([^"]+)" data="([^"]+)" id="[^"]+"', s, re.MULTILINE)
parsed_data = sorted([list(map(lambda x: int(x, 16), i)) + [index] for index,i in enumerate(parsed_data)])
row_numbers = [j for i in [[parsed_data[i][-1], parsed_data[i+1][-1]] for i in range(0,len(parsed_data),2) if parsed_data[i][1] != parsed_data[i+1][1]] for j in i]
final_output = []
for index,line in enumerate(s.split('\n')):
if index in row_numbers:
final_output.append(line)
final_out_text = '\n'.join(final_output)
print(final_out_text)
# info="0x00010AC3" data="0x00000003" id="abc_16. PS"
# info="0x00010ac3" data="0x00000045" id="hB2_RC/BS (Spr)"
You could try something like that too, I think
#!/usr/bin/python3
records = {}
items = []
info = []
data = []
with open("in.dat", "r") as fin:
for line in fin:
items=line.split(' ')
info = items[0].split('=')
data = items[1].split('=')
try:
key = info[1].strip('"').lower()
value = str(int(data[1].strip('"'), 16))
records[key][value] += 1
except KeyError:
try:
records[key][value] = 1
except KeyError:
records[key] = {value: 1}
out = dict()
for key in records:
for value in records[key]:
if records[key][value] == 1:
try:
out[key].append(value)
except KeyError:
out[key] = [value]
with open("out.dat", "w") as fout:
for key in out:
for value in out[key]:
fout.write(f"{key}={value}\n")
Something like this could work:
found_info_values = []
with open("in.txt", "r") as fin,open("out.txt", "w") as fout:
for line in fin:
info = line.split('"')[1]
if info not in found_info_values:
fout.write(line.strip()+'\n')
found_info_values += info

How to completely delete the first line of a text file?

I have a script that outputs a text file (Mod_From_SCRSTXT.txt). I need to delete the first line of that file.
I have tried changing the last line of the find function shown below. The first line still get printed in the new file created even with the changes.
def find(substr, infile, outfile):
with open(infile) as a, open(outfile, 'a') as b:
for line in a:
if substr in line:
b.write(line[1:])
srcn_path1 = input(" Enter Path. Example: U:\...\...\SRCNx\SCRS.TXT\n" +
" Enter SRCS.TXT's Path: ")
print ()
scrNumber1 = input(' Enter SCR number: ')
print ()
def find(substr, infile, outfile):
with open(infile) as a, open(outfile, 'a') as b:
for line in a:
if substr in line:
b.write(line) # or (line + '\n')
# action station:
find(scrNumber1, srcn_path1, 'Mod_From_SCRSTXT.txt')
Actual result:
VSOAU-0004 16999
VSOAU-0004
VSOAU-0004
VSOAU-0004
VSOAU-0004
Expected result:
VSOAU-0004
VSOAU-0004
VSOAU-0004
VSOAU-0004
You'll want to make a minor adjustment:
You can either count the lines in the file:
numberOfLines = 0
for line in file:
numberOfLines += 1
for line in range(1, linesInFile + 1):
Or you can ignore the first line through many different ways, this being a simple one:
ignoredLine = 0
for line in file:
if not ignoredLine:
ignoredLine = 1
else:
#Do stuff with the other lines
import pathlib
import os
import copy
import io
def delete_first_line(read_path):
try:
read_path = pathlib.Path(str(read_path))
write_path = str(copy.copy(read_path)) + ".temp"
while os.path.exists(write_path):
write_path = write_path + ".temp"
with open(read_path , mode = "r") as inf:
with open(write_path, mode="w") as outf:
it_inf = iter(inf)
next(it_inf) # discard first line
for line in it_inf:
print(line, file = outf)
os.remove(read_path)
os.rename(write_path, read_path)
except StopIteration:
with io.StringIO() as string_stream:
print(
"Cannot remove first line from an empty file",
read_path,
file = string_stream,
sep = "\n"
)
msg = string_stream.getvalue()
raise ValueError(msg)
except FileNotFoundError:
with io.StringIO() as string_stream:
print(
"Cannot remove first line from non-existant file",
read_path,
file = string_stream,
sep = "\n"
)
msg = string_stream.getvalue()
raise ValueError(msg)
finally:
pass
return

IndexError: string index out of range <making encrypt, decrypt program>

import random
#get filename
name = input('Enter filename: ')
#load file
try:
input_file = open(name, 'r')
except IOError:
print('File does not exist. Program will terminate.')
#make key value
line = input_file.readline()
key = []
key_mix = []
for i in range(len(line)):
if line[i] not in key:
key.append(line[i])
for i in range(len(line)):
if line[i] not in key_mix:
key_mix.append(line[i])
random.shuffle(key_mix)
#encryption
if name.split('.')[1] == 'txt':
try:
key_file = open(name.split('.')[0] + '.key', 'w')
enc_file = open(name.split('.')[0] + '.enc', 'w')
except IOError:
print('File does not exist. Program will terminate.')
key_write = ['']
for g in range(len(key)):
key_write[0] += key_mix[g]
for i in range(len(key)):
keys = str(key[i]) + ',' + str(key_mix[i])
key_file.write(keys+'\n')
couple = {}
for k in range(len(key)):
couple[key[k]] = key_mix[k]
enc = ['']
for t in range(len(line)):
enc[0] += couple.get(line[t])
enc_file.write(enc[0])
input_file.close()
key_file.close()
enc_file.close()
#decryption
elif name.split('.')[1] == 'enc':
try:
key_file = open(name.split('.')[0] + '.key', 'r')
dec_file = open(name.split('.')[0] + '.txt', 'w')
except IOError:
print('File does not exist. Program will terminate.')
line = input_file.readline()
dec = ['']
sol = {}
while True:
sen = key_file.readline()
if not sen: break
sol.update({sen[2]:sen[0]})*Problem Here*
for m in range(len(line)):
dec[0] += sol.get(line[m])
dec_file.write(dec[0])
input_file.close()
key_file.close()
dec_file.close()
It makes error:
IndexError: string index out of range
and when I check my .key file, it comes like
t,o
h,l
e,s
r,h
i,t
s,r
,n
n,v
o,u
u,e
f,i
l,f
v,
but when I print readline, it comes like
t,o
(blank)
e,s
(blank)
i,t
(blank)
,n
(blank)
o,u
(blank)
f,i
(blank)
v,
(blank)
How can I fix it?

In python, how can I search a specific column for a specific value in a txt file then return the specific value's row?

First of all, I have recently started studying python. So I am a beginner.
1111 1 3
1112 1 2
1113 2 3
1114 1 7
1115 7 2
Assume I have these values in the text file. As in the title, I want to search a specific column for a specific value in the txt file then return the specific value's row except for the searched "value".
Example:
Search the first column for 1113 value.
Then return 2 3 as:
x = 2
y = 3
Try something like this:
with open('file.txt', 'r') as f:
for line in f:
if line.startswith('1113'):
line = line.split()
x = int(line[1])
y = int(line[2])
as 'file.txt' put your file name and as '1113' put the value you are looking for. good luck
You could try this:
import sys
with open( filename, "r" ) as f:
for line in f:
parts = line.split(" ")
if parts[0] == "1113":
print("x={0} y={1}".format( parts[1], parts[2] ))
sys.exit(0)
There is a csv module which will do all the dirty work for you:
import csv
def find(filename, number):
with open(filename) as file:
reader = csv.DictReader(file,
fieldnames=['col1', 'col2', 'col3'],
delimiter=' ')
for line in reader:
if line['col1'] == str(number):
return (line['col2'], line['col3'])
if __name__ == '__main__':
(x, y) = find('data.txt', 1113) or (None, None)
print(x, y)
I'd prefer:
search_text = '1113'
with open(FileName) as f:
for i in f:
if i.strip() != '':
for j in i.strip().split():
if j[0] == search_text:
x = int(i[1])
y = int(i[2])
This will allow you to search for any value on any column.
import csv
def find(reader, col, val):
for row in reader:
if row[col] == val:
return row
raise ValueError('Value {} not found in row {}'.format(val, col))
def findexcept(reader, col, val):
r = find(reader, col, val)
r.pop(col)
return r
with open('searchdata.txt') as f:
lines = (line.strip() for line in f)
c = csv.reader(lines, delimiter=' ', skipinitialspace=True)
try:
x = findexcept(c, 0, '1114')
print(x)
except ValueError as ve:
print('Error: {}'.format(ve))

Parsing through newline characters in Python

I am working on a fairly basic encoder/decoder where you can input your own text file (as a string) and your own encoder (also as a string: it must be a text file).
Here is my decoder function:
def cDecode(file_name, encoder='standard_encoder.txt', save_new=True): # does not decode multi-lines correctly -- everything goes on a single line. See next comment
'''Decodes <'file_name'> with the reverse method of <'encoder'>.'''
if type(file_name) != str or type(encoder) != str: raise TypeError("<'file_name'> and <'encoder'> must be of type <'str'>.")
if type(save_new) != bool: raise TypeError("<'save_new'> must be of type <'bool'>.")
if file_name[-4:] != '.txt': file_name += '.txt'
if encoder[-4:] != '.txt': encoder += '.txt'
decoder_set = {}
try:
with open(encoder, 'r') as encoding_file:
for line in encoding_file:
line_parts = line.split(': ')
my_key, my_value = line_parts[1], line_parts[0]
I think the error is in here:
I have to remove the '\n' because every character (in the decoding file) is on a new line, like such: 'A: Ð'.
if '\n' in my_key:
loc = my_key.find('\n') # this may be the cause of the single-line of the decoding.
my_key = my_key[:loc] + my_key[loc + 1:]
decoder_set[my_key] = my_value
encoding_file.close()
except IOError:
encoder = 'standard_encoder.txt'
with open(encoder, 'r') as encoding_file:
for line in encoding_file:
line_parts = line.split(': ')
my_key, my_value = line_parts[1], line_parts[0]
# every key has a new line character automatically because it's on a different line
if '\n' in my_key:
loc = my_key.find('\n')
my_key = my_key[:loc] + my_key[loc + 1:]
decoder_set[my_key] = my_value
encoding_file.close()
decodingKeys = decoder_set.keys()
Here is the rest of the function:
if save_new:
try:
decoded_file_name = file_name[:-12] + '_decoded' + file_name[-4:]
encoded_file = open(decoded_file_name, 'a+')
with open(file_name, 'r') as my_file:
for line in my_file:
de_line = ''
for char in line:
if char in decodingKeys: de_char = decoder_set[char]
else: de_char = char
de_line += de_char
encoded_file.write(de_line)
except IOError:
raise NameError(file_name + ' was not found. Decoding process terminated.')
else:
try:
import os
encoded_file = file_name[:-12] + '_decoded' + file_name[-4:]
with open(file_name, 'r+') as my_file:
for line in my_file:
de_line = ''
for char in line:
if char in decodingKeys: en_char = decoding_set[char]
else: de_char = char
de_line += de_char
encoded_file.write(de_line)
os.remove(file_name)
os.rename(encoded_file, file_name)
except IOError:
raise NameError(file_name + ' was not found. Decoding process terminated.')
Say I have a multi-line text-file:
This is a test.
As is this one.
Good bye!
When encoded and then decoded afterward, it shows up like this: This is a test.As is this one.Good bye!.
How can I fix this? I'm expecting it to show up like:
This is a test.
As is this one.
Good bye!
Thanks!
Add a '\n' while writing back the line to file:
encoded_file.write(de_line+'\n')

Categories