open and write statements in Fortran - file-io

I am working through the Fortran tutorial at http://en.wikibooks.org/wiki/Fortran/Fortran_simple_input_and_output. In the following program, what does unit=out_unit do?
program xproduct
implicit none
integer :: i,j
integer, parameter :: out_unit=20
print*,"enter two integers"
read (*,*) i,j
open (unit=out_unit,file="results.txt",action="write",status="replace")
write (out_unit,*) "The product of",i," and",j
write (out_unit,*) "is",i*j
close (out_unit)
end program xproduct
When I run this program, the text file results.txt contains the following text:
The product of 2 and 3
is 6

It specifies the "terminal" to write to. The number contained in out_unit represents the file you opened with the open statement. If you hadn't used the open statement and specified the file, output would have been to fort.20
Some terminal numbers have specific meanings. For example, 6 is (usually) stdout, and 5 is (usually) stdin.

In the following program, what does unit=out_unit do?
It's using named function parameters.
From Wikipedia:
Named parameters or keyword arguments refer to a computer language's support for function calls that clearly state the name of each parameter within the function call itself.
A function call using named parameters differs from a regular function call in that the values are passed by associating each one with a parameter name, instead of providing an ordered list of values.

Related

SCIP - run (nearly) same LP on different instances

I have an LP, formulated in the modelling language Zimpl, that I want to run on many instances, which are in different files.
Additionally, I want to change one parameter in this LP.
For a single call, my file test.zpl looks like this:
param FILE := "file1.dat"
param BOUND := 42
[test_body: Rest of LP]
Now I want to change those two parameters. SCIP has the -c option, to execute some command. But I cannot find by which command to achieve this. All parameter changes I found affect the algorithm, not the data.
The command change to change the problem does not seem to allow new parameters/variables.
In the end, I expect the solution to look something like
scip -c "[set my parameters]; read test_body.zpl; optimize; quit"
How do I set these problem parameters?
I am not aware of any commands that support the modification of model parameters as you wish. However, if you don't hardcode the value of param BOUND in the .zpl file (instead, move the value to the .dat file and use a proper read command in the model), then you could procede as follows:
Make a copy of your data file such that each copy contains a distinct value of param BOUND
Call scip.exe separately with each data file (you could also use a simple batch script)

Syntax error in INQUIRE(inpunit,flen=iflen) in gfortran but not in Lahey

I try to compile my code using gfortran. I got this error:
**INQUIRE(inpunit,flen=iflen)
1
Error: Syntax error in INQUIRE statement at (1)**
This code was compiled before with lahey. With a quick research I find that parameters of INQUIRE have different meaning in gfortran compared to lahey.
inpunit is a scalar INTEGER expression that evaluates to the
input/output unit number of an external file.
flen is a scalar default INTEGER variable having the length of the file in bytes.
My question is when using gfortran is this statement correct to get the same functionality as in Lahey:
**INQUIRE(inpunit,RECL=iflen) **
Are these two statements similar?
Thanks
No, these two are completely different.
flen= is a nonstandard extension specific to the Leahy compiler and returns the length of the file.
recl= is the maximum record length in the file (if the file is connected - opened, otherwise it is 0) https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-inquire-recl-specifier
To be standard conforming you should use size=. Be aware that the result will be in file storage units. Gfortran uses bytes, but other compilers may use 4-byte words.
See What is a good way to get file size in bytes using Fortran (ifort)? Find input file size in fortran90

How to run a program with parameters (Pick BASIC)

In Pick BASIC source code I see lines such as
CALL SOMEPROGRAM (PARAM1, PARAM2)
How can I invoke that same line from the TCL command prompt? I've tried variations of the following but nothing seems to work.
SOMEPROGRAM ('1','2')
The only way I've found is to write and compile a program with the single line command and then run that program.
If this was your routine:
SUBROUTINE REALPROG(A,B)
PRINT "A is ":A
PRINT "B is ":B
END
To call it from command line, you'd build this routine:
PROGRAM WRAPPERPROG
COMMAND.RECEIVED = SENTENCE()
VAR1 = FIELD(COMMAND.RECEIVED,' ',2)
VAR2 = FIELD(COMMAND.RECEIVED,' ',3)
CALL REALPROG(VAR1, VAR2)
END
Assuming you typed this from the TCL/ECL command line:
WRAPPERPROG DOG CAT
VAR1 would be DOG and VAR2 would be CAT
...and would call REALPROG with those parameters and you should see
A is DOG
B is CAT
Tcl can invoke your overall program file as a subprocess using exec, but it is up to your program to turn that into a call to the program and processing of correct arguments.
The Tcl code to run the program will probably look something like this:
exec {*}[auto_execok CALLERPROGRAM]
If you were passing the arguments 1 and 2 over, you'd do this:
exec {*}[auto_execok CALLERPROGRAM] 1 2
Again, that does not say how those values get from the command line into the Pick Basic subprogram. You'll need to consult the Pick documentation for how to do that. But I know (and have tested) that Tcl will definitely have correctly provided them…
In Pick BASIC CALL statements are used to call subroutines and they can't be directly executed from TCL. Subroutines are denoted by setting the first word on the first line of the program to SUBROUTINE.
You can execute "programs" from TCL. These don't include the SUBROUTINE at the top of the source code. In some Pick BASIC variants you may need to include PROGRAM but I think most don't require that (I know D3 doesn't). These programs can be run from TCL but they don't get the command line parameters passed in automatically like subroutines do. I think you can use SENTENCE() in pretty much any Pick BASIC variant to get the command line parameters.
Here's an example program that will print the command line arguments:
PRINT SENTENCE()
END
You could use this to create a program that will take the command line arguments and pass them into a subroutine to do something for you.
I was literally typing out some elaborate answer, but your question has been answered. You cant directly call a subroutine, you need to call a program that calls the subroutine. Also subroutines are a good way to separate code from the main program to reduce clutter, but they arent always necessary. Other methods you can use are functions, or GOSUBS/GOTOS. This is an example of a GOTO below..
VAR = 'HELLO'
GOTO 10:
10:
CRT VAR
from the TCL you will call the name of your program and all of this code will be executed without calling another program.
The output will be the string hello.
I wrote a utility 30+ years ago to address this. Other Basics (QB, VB, Dartmouth) have a single command line. You are either writing lines into a program or processing single line requests. Pick did not.
I created an MD item called PRINT. It then runs a program called BP PRINT that takes the whole TCLREAD line, writes it out to another program space called BP PPRINT, compiles it and then runs it.
Incredibly useful. Thus at TCL these commands would work:
PRINT ; X=1 ; Y=2 ; CALL SOMESUB(X,Y)
PRINT ; FOR I=1 TO 12 ; PRINT (I*28)"DMA" ; NEXT I
PRINT ; OPEN "CUST" THEN READV NAME FROM "1234", 1 THEN PRINT NAME
PRINT OCONV("12345678","MD2Z,$")
PRINT DATE()
Basically anything that can be programmed within a single line of code can be typed at TCL this way. Any IF or ELSE statements must be completed in the same one line. Great for testing.
Should be part of every Pick implementation out of the box.
Mark Johnson

stat function for perl6

Is there an alternate way in perl6 to get file attribute details like size, access_time, modified_time.. etc. without having to invoke native call?
As per the doc it is "unlikely to be implemented as a built in as its POSIX specific".
What workaround options are available excluding the system call to stat?
Any ideas or pointers are much appreciated.
Thanks.
See the IO::Path doc.
For example:
say 'foo'.IO.s; # 3 if 'foo' is an existing file of size 3 bytes
.IO on a string creates an IO::Path object corresponding to the filesystem entry corresponding to the path given by the string.
See examples of using junctions to get multiple attributes at the same time at the doc on ACCEPTS.
I'm not sure if the following is too much. Ignore it if it is. Hopefully it's helpful.
You can discover/explore some of what's available in Perl 6 via its HOW objects (aka Higher Order Workings objects, How Objects Work objects, metaobjects -- whatever you want to call them) which know HOW objects of a particular type work.
say IO::Path.^methods
displays:
(BUILD new is-absolute is-relative parts volume dirname basename extension
Numeric sibling succ pred open watch absolute relative cleanup resolve
parent child add chdir rename copy move chmod unlink symlink link mkdir
rmdir dir slurp spurt lines comb split words e d f s l r w rw x rwx z
modified accessed changed mode ACCEPTS Str gist perl IO SPEC CWD path BUILDALL)
Those are some of the methods available on an IO::Path object.
(You can get more or less with adverbs, eg. say IO::Path.^methods(:all), but the default display aims at giving you the ones you're likely most interested in. The up arrow (^) means the method call (.methods) is not sent to the invocant but rather is sent "upwards", up to its HOW object as explained above.)
Here's an example of applying some of them one at a time:
spurt 'foo', 'bar'; # write a three letter string to a file called 'foo'.
for <e d f s l r w rw x rwx z modified accessed changed mode>
-> $method { say 'foo'.IO."$method"() }
The second line does a for loop over the methods listed by their string names in the <...> construct. To call a method on an invocant given it's name in a variable $qux, write ."$qux"(...).
While looking for an answer to this question in 2021, there is the File::Stat module. It provides some additional stat(2) information such as UID, GID and mode.
#!/usr/bin/env raku
use File::Stat <stat>;
say File::Stat.new(path => $?FILE).mode.base(8);
say stat($?FILE).uid;
say stat($?FILE).gid;

program to reproduce itself and be useful -- not a quine

I have a program which performs a useful task. Now I want to produce the plain-text source code when the compiled executable runs, in addition to performing the original task. This is not a quine, but is probably related.
This capability would be useful in general, but my specific program is written in Fortran 90 and uses Mako Templates. When compiled it has access to the original source code files, but I want to be able to ensure that the source exists when a user runs the executable.
Is this possible to accomplish?
Here is an example of a simple Fortran 90 which does a simple task.
program exampl
implicit none
write(*,*) 'this is my useful output'
end program exampl
Can this program be modified such that it performs the same task (outputs a string when compiled) and outputs a Fortran 90 text file containing the source?
Thanks in advance
It's been so long since I have touched Fortran (and I've never dealt with Fortran 90) that I'm not certain but I see a basic approach that should work so long as the language supports string literals in the code.
Include your entire program inside itself in a block of literals. Obviously you can't include the literals within this, instead you need some sort of token that tells your program to include the block of literals.
Obviously this means you have two copies of the source, one inside the other. As this is ugly I wouldn't do it that way, but rather store your source with the include_me token in it and run it through a program that builds the nested files before you compile it. Note that this program will share a decent amount of code with the routine that recreates the code from the block of literals. If you're going to go this route I would also make the program spit out the source for this program so whoever is trying to modify the files doesn't need to deal with the two copies.
My original program (see question) is edited: add an include statement
Call this file "exampl.f90"
program exampl
implicit none
write(*,*) "this is my useful output"
open(unit=2,file="exampl_out.f90")
include "exampl_source.f90"
close(2)
end program exampl
Then another program (written in Python in this case) reads that source
import os
f=open('exampl.f90') # read in exampl.f90
g=open('exampl_source.f90','w') # and replace each line with write(*,*) 'line'
for line in f:
#print 'write(2,*) \''+line.rstrip()+'\'\n',
g.write('write(2,*) \''+line.rstrip()+'\'\n')
f.close
g.close
# then complie exampl.f90 (which includes exampl_source.f90)
os.system('gfortran exampl.f90')
os.system('/bin/rm exampl_source.f90')
Running this python script produces an executable. When the executable is run, it performs the original task AND prints the source code.