Basically I need to read from file char by char and I need to know at which line that character was. So it's a loop inside a loop.
keyboard = open(default_layout, 'r')
with open(default_layout) as l:
for line in l:
queue=0
#i=i+1
while queue != max_chars_per_key:
c = l.read(1)
<...>
if (queue==0):
key_name=c
key[c] = [key_name, queue+1]
<...>
queue+=1
<...bunch of code...>
The problem is, with this code after passing parameters it gives me:
ValueError: Mixing iteration and read methods would lose data
Any ideas on workaround?
The simplest way to get what you want would be:
with open(...) as fh:
for line_num, line in enumerate(fh):
for col_num, char in enumerate(line):
...
To put that into context with your code, it would be roughly:
keyboard = open(default_layout, 'r')
with open(default_layout) as l:
for line in l:
queue = 0
for c in line[:max_chars_per_key]:
...
if queue == 0:
key_name=c
key[c] = [key_name, queue+1]
...
queue += 1
...
Related
I have to create a function that removes duplicate characters from a string. There are many questions regarding this same topic, but the difference is that when removing the string, it has to evaluate if the character is equal to the one before it. For example: if the string is "teeth", the output must be "teth". The code I have now:
def remove_duplicates(s):
result = ""
for char in s:
if char :
"".join(result)
print(char)
return result
If anyone can help, it would be appreciated.
def remove_duplicates(s):
result = ""
per_char = None
for char in s:
if per_char != char:
result += char
per_char = char
return result
filelist.txt contains a list of files:
/path/file1.json
/path/file2.json
/path/fileN.json
Is there a (simple) MATLAB command that will accept filelist.txt and read each file as a string and store each string into a cell array?
Just use readtable, asking it to read each line in full.
>> tbl = readtable('filelist.txt','ReadVariableNames',false,'Delimiter','\n');
>> tbl.Properties.VariableNames = {'filenames'}
tbl =
3×1 table
filenames
__________________
'/path/file1.json'
'/path/file2.json'
'/path/fileN.json'
Then access the elements in a loop
for idx = 1:height(tbl)
this_filename = tbl.filenames{idx};
end
This problem is a bit to specific for a standard function. However, it is easily doable with the combination of two functions:
First, you have to open the file:
fid = fopen('filelist.txt');
Next you can read line by line with:
line_ex = fgetl(fid)
This function includes a counter. If you call the function the next time, it will read the second line and so on. You find more information here.
The whole code might look like this:
% Open file
fid = fopen('testabc');
numberOfLines = 3;
% Preallocate cell array
line = cell(numberOfLines, 1);
% Read one line after the other and save it in a cell array
for i = 1:numberOfLines
line{i} = fgetl(fid);
end
% Close file
fclose(fid);
For this replace the for loop with a while loop:
i=0;
while ~feof(fid)
i=i+1
line{1} = fgetl(fid)
end
Alternative to while loop: Retrieve the number of lines and use in Caduceus' for-loop:
% Open file
fid = fopen('testabc');
numberOfLines = numlinestextfile('testable'); % function defined below
% Preallocate cell array
line = cell(numberOfLines, 1);
% Read one line after the other and save it in a cell array
for i = 1:numberOfLines
line{i} = fgetl(fid);
end
% Close file
fclose(fid);
Custom function:
function [lineCount] = numlinestextfile(filename)
%numlinestextfile: returns line-count of filename
% Detailed explanation goes here
if (~ispc) % Tested on OSX
evalstring = ['wc -l ', filename];
% [status, cmdout]= system('wc -l filenameOfInterest.txt');
[status, cmdout]= system(evalstring);
if(status~=1)
scanCell = textscan(cmdout,'%u %s');
lineCount = scanCell{1};
else
fprintf(1,'Failed to find line count of %s\n',filenameOfInterest.txt);
lineCount = -1;
end
else
if (~ispc) % For Windows-based systems
[status, cmdout] = system(['find /c /v "" ', filename]);
if(status~=1)
scanCell = textscan(cmdout,'%s %s %u');
lineCount = scanCell{3};
disp(['Found ', num2str(lineCount), ' lines in the file']);
else
disp('Unable to determine number of lines in the file');
end
end
end
I cannot figure this one out. When I remove let size = s.readInt64() from the following proc, the .exe seems to terminate before it reaches the end. It is declared but not used! Its gotta go!
proc load(fn: string): Alternating =
var s = newFileStream(fn, fmRead)
let size = s.readInt64() #WITHOUT THIS LINE THE .exe doesn't execute ExitTerminal()
result = newSeq[(float, int)]()
while not s.atEnd:
let element = (s.readFloat64.float, s.readInt64.int)
result.add(element)
s.close()
Below is the entire program. The file type is .dat and I suppose it is binary. It is created in the program. I compiled with -d:release Nim version 0.18.0 and minGW compiler
import streams
type
Alternating = seq[(float, int)]
proc store(fn: string, data: Alternating) =
var s = newFileStream(fn, fmWrite)
s.write(data.len)
for x in data:
s.write(x[0])
s.write(x[1])
s.close()
proc load(fn: string): Alternating =
var s = newFileStream(fn, fmRead)
let size = s.readInt64() #WITHOUT THIS LINE THE .exe doesn't execute ExitTerminal()
result = newSeq[(float, int)]()
while not s.atEnd:
let element = (s.readFloat64.float, s.readInt64.int)
result.add(element)
s.close()
let data = #[(1.0, 1), (2.0, 2)]
store("tmp.dat", data)
let dataLoaded = load("tmp.dat")
echo dataLoaded
### EXIT PROCEDURE FROM TERMINAL PROGRAM
proc ExitTerminal: bool =
echo "Exit Application"
echo "(y/n)"
while true:
case readline(stdin)
of "y", "Y", "yes", "Yes": return true
of "n", "N", "no", "No": return false
else: echo "Please be clear: yes or no"
if ExitTerminal() == false: discard ExitTerminal()
It is hard to tell because we know nothing about the file format you're reading. But generally you can't remove s.readInt64() just because it is unused, because apart from reading this proc advances your stream cursor. If you need to ignore the value just use discard s.readInt64() # Ignore size
I am having trouble with convert this single line loop into multiple line code in python.
text_data = [''.join(char for char in sent if char not in punct) for sent in text_data]
Thanks in advance.
UPDATE
solved it.
out_list = []
for sent in test_data:
out_str = ''
for char in sent:
if char not in punct:
out_str = out_str+char
out_list.append(out_str)
thanks for the help
you can try following snippet for your nested one line for loop
out_list = []
for sent in text_data:
out_str = ''
for char in sent:
if char not in punct:
out_str.join(char)
out_list.append(out_str)
I have a fairly large text file and am trying to search for a particular term so that i can start a process after that point, but this doesn't seem to be working for me:
fileID = fopen(resfile,'r');
line = 0;
while 1
tline = fgetl(fileID);
line = line + 1;
if ischar(tline)
startRow = strfind(tline, 'OptimetricsResult');
if isfinite(startRow) == 1;
break
end
end
end
The answer I get is 9, but my text file:
$begin '$base_index$'
$begin 'properties'
all_levels=000000000000
time(year=000000002013, month=000000000006, day=000000000020, hour=000000000008, min=000000000033, sec=000000000033)
version=000000000000
$end 'properties'
$begin '$base_index$'
$index$(pos=000000492036, lin=000000009689, lvl=000000000000)
$end '$base_index$'
definitely doesn't have that in the first 9 rows?
If I ctrl+F the file, I know that OptimetricsResult only appears once, and that it's 6792 lines down
Any suggestions?
Thanks
I think your script somehow works, and you were just looking at the wrong variable. I assume that the answer you get is startRow = 9 and not line = 9. Check the variable line. By the way, note that you're not checking an End-of-File, so your while loop might run indefinitely the file doesn't contain your search string.
An alternative approach, (which is much simpler in my humble opinion) would be reading all lines at once (each one stored as a separate string) with textscan, and then applying regexp or strfind:
%// Read lines from input file
fid = fopen(filename, 'r');
C = textscan(fid, '%s', 'Delimiter', '\n');
fclose(fid);
%// Search a specific string and find all rows containing matches
C = strfind(C{1}, 'OptimetricsResult');
rows = find(~cellfun('isempty', C));
I can't reproduce your problem.
Are you sure you've properly closed the file before re-running this script? If not, the internal line counter in fgetl does not get reset, so you get false results. Just issue a fclose all on the MATLAB command prompt, and add a fclose(fileID); after the loop, and test again.
In any case, I suggest modifying your infinite-loop (with all sorts of pitfalls) to the following finite loop:
haystack = fopen(resfile,'r');
needle = 'OptimetricsResult';
line = 0;
found = false;
while ~feof(haystack)
tline = fgetl(haystack);
line = line + 1;
if ischar(tline) && ~isempty(strfind(tline, needle))
found = true;
break;
end
end
if ~found
line = NaN; end
fclose(fileID);
line
You could of course also leave the searching to more specialized tools, which come free with most operating systems:
haystack = 'resfile.txt';
needle = 'OptimetricsResult';
if ispc % Windows
[~,lines] = system(['find /n "' needle '" ' haystack]);
elseif isunix % Mac, Linux
[~,lines] = system(['grep -n "' needle '" ' haystack]);
else
error('Unknown operating system!');
end
You'd have to do a bit more parsing to extract the line number from C, but I trust this will be no issue.