I am very new to J (learning it for fun) and I am trying to read data from keyboard. I have tried to make a tiny script which reads in a string and reverses it:
|.(1!:1 3)
When I run it, I get a rank error. (I'm using 1!:1 3 instead of defining a verb because codegolf...)
Is there a command that can check the rank of 1!:1 3?
That's a common mistake with foreigns.
The definition for foreign 1!:1 doesn't help, because it really reads:
1!:1 y Read. y is a file name or a file number (produced by 1!:21); the
result is a string of the file contents., e.g. 1!:1 <'abc.q'. The following
values for y are also permitted:
1 read from the keyboard (does not work within a script)
3 read from standard input (stdin)
And so replacing y with 3 should work, right? Well, not quite, because what you're really giving as an argument in writing:
1!:1 3
is an array made of 1 3. Sort of like giving it:
1!:(1 3)
when you want:
1!:1 (3)
For code golf purposes, use a right bracket:
1!:1]3
Related
yy and p should copy and paste 1 line of text.
But I have to go back and delete the original line.
:2,5m10
should move lines from 2 to 5 to line 10. however I need to enable :set number
to see what lines I am moving
I would like to move just 1 line of text, sort of like yy+p and not use :2,3m10
to move just one line.
Is there something like mm+p ?
so it copies the current line into buffer and deletes the line and you p paste it where you want ?
:3m . moves line 3 to your current line.
Above line does the function I want. Can I set a key mapping so
that "mm" replaces ":3m." ? I find it easier to type. TIA
What you're describing is the default behaviour when using dd -it deletes a
line into the buffer and p will paste it.
So dd and p works.
If you're new to vim, then it might seem a little strange that 'yanking' (with
y) and 'deleting' (with d) both copy to the buffer, given the 'cut', 'copy'
and 'paste' behaviours of most other editors.
You can read more about it with :help change.txt and in particular :help registers.
Also, since you say you need to enable :set number, I wonder if you've come
across :set relativenumber? This is very useful - in the example below, the
numbers would look this way if the your cursor was on the line with
'demonstrate':
3 This is just
2 a small
1 example to
0 demonstrate
1 how relative
2 numbers can
3 be useful
Thus if you wanted to move the line 'a small' below the line with 'numbers
can', you could use the relative line numbers to know that 2k would put the
cursor on the line you want, where you'd hit dd, then you'd have this
situation (the deleted line is now in the buffer:
1 This is just
0 example to
1 demonstrate
2 how relative
3 numbers can
4 be useful
Then you can do 3j to move to the 'numbers can' line, and hit p. So
relative numbers are a nice way to move quickly to lines you can see. Also,
just for completeness, you can use relative numbers in a similar way on the
command line::-2m+3 (although I know this isn't what you're after). You can
even set both relative number and set number at the same time, in which case
it's like in the example above, only you have the absolute line number
displayed on the current line instead of a zero.
How do I fix the Fortran runtime error: Bad integer for item 0 in list input?
Below is the Fortran program which generates a runtime error.
CHARACTER CNFILE*(*)
REAL BOX
INTEGER CNUNIT
PARAMETER ( CNUNIT = 10 )
INTEGER NN
OPEN ( UNIT = CNUNIT, FILE = CNFILE, STATUS = 'OLD' )
READ ( CNUNIT,* ) NN, BOX
The error message received from gdb is :
At line 688 of file MCNPT.f (unit = 10, file = 'LATTICE-256.txt')
Fortran runtime error: Bad integer for item 0 in list input
[Inferior 1 (process 3052) exited with code 02]
(gdb)
I am not sure what options must be specified for READ() to read to numbers from the text file. Does it matter if the two numbers on the same line are specified as either an integer or a real in the text file?
Below is the gdb execution of the program using a break point at the open call
Breakpoint 1, readcn (
cnfile=<error reading variable: Cannot access memory at address 0x7fffffffdff0>,
box=-3.37898272e+33, _cnfile=30) at MCNPT.f:686
Since you did not specify form="unformatted" on the open statement, the unit / file is opened for formatted IO. This is appropriate for a human-readable text file. ("unformatted" would be used for a non-human readable file in computer-native format, sometimes called "binary".) Therefore you should provide a format on the read, or use list-directed read, i.e., read(unit, *). To advise on a particular format we would have to know the layout of the numbers in the file. A possible read with format is: read (CNUINT, '(I4, 2X, F6.2)' ) NN, BOX
P.S. I'm answering the question in your question and not the title, which seems unrelated.
EDIT: now that you are show the text data file, a list-directed read looks easier. That is because the data doesn't line up in columns. It seems that the file has two integers on the first line, then three real numbers on each of the following lines. Most likely you need a different read for the first line. Is the code sample that you are showing us trying to read the first line, or one of the later lines? If the first line, it would seem plausible to read into two integer variables. If a later line, into two or three real variables. Two if you wish to skip the third data item on the line.
EDIT 2: the question has been substantially altered several times, which is very confusing. The first line of the text file that was shown in one version of the question contained integers, with later lines having reals. Since the listed-directed read is reading into an integer and a floating variable, it will have problems if you attempt to use it on the later lines that have two real values.
How do we read a specific file line by line while skipping some columns in it?
For example, I have a text file which has data, sorted out in 5 columns, but I need to read only two columns out of it, they can be first two or any other random combination (I mean, need a solution which would work with any combination of columns like first and third only).
Code something like this
open(1, file=data_file)
read (1,*) ! to skip first line, with metadata
lmax = 0
do while (.true.)
! read column 1 and 3 here, either write
! that to an array or just loop through each row
end do
99 continue
close (1)
Any explanation or example would help a lot.
High Performance Mark's answer gives the essentials of simple selective column reading: one still reads the column but transfers it to a then-ignored variable.
To extend that answer, then, consider that we want to read the second and fourth columns of a five-column line:
read(*,*) junk, x, junk, y
The first value is transferred into junk, then the second into x, then the third (replacing the one just acquired a moment ago) into junk and finally the fourth into y. The fifth is ignored because we've run out of input items and the transfer statement terminates (and the next read in a loop will go to the next record).
Of course, this is fine when we know it's those columns we want. Let's generalize to when we don't know in advance:
integer col1, col2 ! The columns we require, defined somehow (assume col1<col2)
<type>, dimension(nrows) :: x, y, junk(3) ! For the number of rows
integer i
do i=1,nrows
read(*,*) junk(:col1-1), x(i), junk(:col2-col1-1), y(i)
end do
Here, we transfer a number of values (which may be zero) up to just before the first column of interest, then the value of interest. After that, more to-be-ignored values (possibly zero), then the final value of interest. The rest of the row is skipped.
This is still very basic and avoids many potential complications in requirements. To some extent, it's such a basic approach one may as well just consider:
do i=1,nrows
read(*,*) allofthem(:5)
x(i) = allofthem(col1)
y(i) = allofthem(col2)
end do
(where that variable is a row-by-row temporary) but variety and options are good.
This is very easy. You simply read 5 variables from each line and ignore the ones you have no further use for. Something like
do i = 1, 100
read(*,*) a(i), b, c(i), d, e
end do
This will overwrite the values in b, d, and e at every iteration.
Incidentally, your line
99 continue
is redundant; it's not used as the closing line for the do loop and you're not branching to it from anywhere else. If you are branching to it from unseen code you could just attach the label 99 to the next line and delete the continue statement. Generally, continue is redundant in modern Fortran; specifically it seems redundant in your code.
I want to read in data from multiple files that I want to use for plotting (matplotlib).
I found a function loadtxt() that I could use for this purpose. However, I only want to read in one column from each file.
How would I do this?
The following command works for me if I read in at least 2 columns, for example:
numpy.loadtxt('myfile.dat', usecols=(2,3))
But
numpy.loadtxt('myfile.dat', usecols=(3))
would throw an error.
You need a comma after the 3 in order to tell Python that (3,) is a tuple. Python interprets (3) to be the same value as the int 3, and loadtxt wants a sequence-type argument for usecols.
numpy.loadtxt('myfile.dat', usecols=(3,))
I need to write some data to file in Fortran 90. How should I use WRITE (*,*) input to have the values grouped in columns? WRITE always puts a new line after each call, that's the problem.
code example:
open (unit = 4, file = 'generated_trajectories1.dat', form='formatted')
do time_nr=0, N
write (4,*) dble(time_nr)*dt, initial_traj(time_nr)
end do
And now the point is to have it written in separate columns.
You can use implied DO loops to write values as single records. Compare the following two examples:
integer :: i
do i=1,10
write(*,'(2I4)') i, 2*i
end do
It produces:
1 2
2 4
3 6
...
Using implied DO loops it can rewritten as:
integer :: i
write(*, '(10(2I4))') (i, 2*i, i=1,10)
This one produces:
1 2 2 4 3 6 ...
If the number of elements is not fixed at compile time, you can either use the <n> extension (not supported by gfortran):
write(*, '(<n>(2I4))') (i, 2*i, i=1,n)
It takes the number of repetitions of the (2I4) edit descriptor from the value of the variable n. In GNU Fortran you can first create the appropriate edit descriptor using internal files:
character(len=20) :: myfmt
write(myfmt, '("(",I0,"(2I4))")') n
write(*, fmt=myfmt) (i, 2*i, i=1,n)
Of course, it also works with list directed output (that is output with format of *):
write(*, *) (i, 2*i, i=1,10)
This really depends on what data you are trying to write to file (i.e. whether you have a scalar within a loop or an array...). Can you include a description of this in your question?
If your are trying to write a scalar multiple times to the same row then try using non-advancing I/O, passing the keyword argument advance="no" to the write statement, e.g.
integer :: x
do x = 1,10
write(*, fmt='(i4,1x)', advance="no") x
end do
However, be aware of a suprise with non-advancing I/O.
The answer depends on your answer to Chris's question. If you want a single line, then you will have to use non-advancing IO as described by Chris. Without this, with multiple formatted write statement you will always get multiple lines.
Also, you will likely need to use formatted IO instead of list-directed (*) IO. The rules are loose for list-directed IO. Different compilers may produce different output. With many output items, line breaks are likely to keep the output lines from being too long.
Here a format that should work if all of your variables are reals:
write (4, '( *(2X, ES14.6) )', advance="no" )
how about the good old $ edit descriptor:
write(*, fmt='(i4,$)') x
remember to do a write(*,*) after your loop...