How to pre-fill a READ statement variable in Fortran? - fortran

I have a program that has a menu with multiple options (search record, add record, delete record, modify record). What I am trying to do is sort of an autofill function.
Ex: A record number is entered into the search option, but after searching through the database, that record is not found. You are then prompted with the option of searching for a different record number or adding a new record with the variable you just entered. If you choose to add, I want the program to call the add subroutine, and already autofill the read statement with the record you read in to you search subroutine.
This what my code looks like (the search subroutine uses a search function to lookup the record number in master.db, and the display subroutine prints out the results on the screen in a formatted array; both the search and display use a master module with the character and integer variables in the record defined):
SUBROUTINE search
IMPLICIT NONE
CHARACTER::readRecord*10, changeOpt*1
INTEGER::recNum, search
OPEN(20, FILE="master.db", FORM="FORMATTED", ACCESS="DIRECT", RECL=100)
DO
CALL SYSTEM ("clear")
WRITE(*,"(2/,20X,A25)")"* * * Search Record * * *"
WRITE(*,100,ADVANCE="NO")"Please enter a record number or Q to exit:"
100 FORMAT(1/,20X,A42,1X)
READ(*,200)readRecord
200 FORMAT(A10)
IF(readSSN=="Q" .OR. readSSN=="q")RETURN
recNum=search(readRecord)
IF (recNum==0)THEN
CALL SYSTEM("clear")
WRITE(*,"(2/,20X,A26)")"* * * Display Record * * *"
WRITE(*,300,ADVANCE="NO")"Record ", readRecord," not found. ","Would you like to add a new record (Y/N)?"
300 FORMAT(1/,20X,A7,A10,A12,1/,20X,A41,1X)
READ*,changeOpt
IF(changeOpt=="Y" .OR. changeOpt=="y") CALL add
CYCLE
ELSE
CALL display
WRITE(*,400,ADVANCE="NO")"Press ENTER to continue:"
400 FORMAT(1/,20X,A24,1X)
READ*,
END IF
END DO
CLOSE(20)
END SUBROUTINE search
In the add subroutine, everything up to
recNum=search(readRecord)
is identical to the search subroutine. What I want is a way to take the information entered to
READ(*,200)readRecord
in the search subroutine, somehow temporarily save it, and then once the add subroutine is called, automatically enter it into the
READ(*,200)readRecord
in the add subroutine, so that the user doesn't have to re-enter the record number they want to add.
A way I think this might be accomplished, but I don't know the syntax for would be:
! WRITE readRecord to some specific place in master.mod
! CALL add
! Once in add:
! At READ(*,200)readRecord, search police.mod to check if it
! has a readRecord already written in it.
! If it does, autofill READ(*,200)readRecord with the readRecord
! from police.mod.
! Then delete readRecord from police.mod (so that if you go directly
! into the add subroutine later, it doesn't autofill a record from a
! previous search).
! If there is no readRecord in police.mod then just prompt for user
! to enter readRecord like in the search subroutine.
Any suggestions would be greatly appreciated.

You do not say that clearly, but I assume that by "autofill the READ variable" you want that the string is pre-filled on the screen in the prompt and the user can edit it or just hit Enter.
That is not possible in Fortran with the readstatement. The statement does not work this way and has no such option.
You can achieve similar things with certain libraries. They are usually written in C. You won't be able to use the read statement in them though and they are usually written in C. For example the readline and ncurses libraries. See related
pre-fill stdin in C
What you can do in standard Fortran is to have an if condition and check if the user decided to enter an empty string and use some default previous value if that happened.

Related

How to get total increments in Disp subroutine in ABAQUS

I am using Disp subroutine in ABAQUS. I want to apply a specific boundary condition to my model. This a part of my code:
IF (NODE==mst(2,1)) THEN
IF (JDOF .EQ. 1) THEN
U(1)=0.01
ELSE IF (JDOF .EQ. 2) THEN
U(1)=0
ELSE
U(1)=0
END IF
END IF
The problem is that I do not know how many incerement does ABAQUS use to solve the model. Thus, I do not know how to change the value of "U(1)=0.01" to its incremental. I know that "KINC" gives the current increment number. However, I do not know how to get the total number of increments. Morover, is there any need to change the value to incremental or ABAQUS would do it automatically?
The total number of increments is not known a priori unless you specify it (i.e. if it has troubles converging, it will decrease the step size and thus increase the step number). You can use TIME(1) and TIME(2) to know the current value of step time and reformulate your load based on that, which I think is what you're looking for.
For the second question, Abaqus will compute the increment automatically or follow a specified depending on the solver settings you prescribe. There are some user subroutines that can control the increment size but DISP is not one of them.

Passing variable from one iMacros to another?

I want to create a script, where the users inputs in the beginning something, and this variable input should be used for the rest of the loop (without asking for input again).
The best way i could come up with was to create two iMacros, one which asks for the input, and the other one who uses the input and loops it.
The major problem is, i can't save the input in Downloads/Datasource because the same iMacros should be used with other firefox instances. Which means, if the user inputs A on the first instance and on the next B then after the second loop of both all instances are using the varaible B. And i can't make multiple scripts since the user should have the ability to use unlimited times this script.
You can save easy the input in ‘Downloads/Datasource’. However make your second macro read this input only once:
SET !LOOP 1
SET !DATASOURCE inputs.csv
SET input EVAL("('{{!LOOP}}' == 1) ? '{{!COL1}}' : '{{input}}';")
' your further code here '

Fortran "write" column limit? [duplicate]

I've spent hours scouring the internet for a solution to this problem and can't find anything. I have been trying to write unformatted output to a CSV output file with multiple very long lines of varying length and multiple data types. I'm trying to first write a long header that indicates the variables that will be written below, separated by commas. Then on the lines below that, I am writing the values specified in the header. However, with sequential access, the long output lines are broken into multiple shorter lines, which is not what I was hoping for. I tried controlling the line length using recl in the open statement, but that only added a bunch of garble text and symbol after the output with the same problem still occurring. I also tried using direct access but the lines are not the same length so that would not work either. I've read about using stream i/o in Fortran2003 but I'm using Fortran90, so that won't work either. I am using Fortran 90 with the Plato IDE which uses the FTN95 compiler. I included an example program similar to what I want to do below, using an array and some dummy text, and I've included the output below that illustrating the problem. Anyone know how I can just one line per write statement? Any help would be greatly appreciated.
module types
integer, parameter :: dp=selected_real_kind(15)
end module types
program blah
use types
use inputoutput
implicit none
integer :: i
character(50)::fileNm
integer :: unitout2=20
real(dp), dimension(100) :: bigArray
fileNm='predictout2.csv'
open(unit=unitout2,file=fileNm,status="replace")
do i=1,100
bigArray(i)=i
end do
write(unitout2,*)"word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,&
&word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,&
&word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word"
write(unitout2,*)bigArray
close(unitout2)
end program
Here's the output for the program above (without recl):
word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word
,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,word,wo
rd,word,word,word,word,word
1.00000000000 2.00000000000 3.00000000000 4.00000000000
5.00000000000 6.00000000000 7.00000000000 8.00000000000
9.00000000000 10.0000000000 11.0000000000 12.0000000000
13.0000000000 14.0000000000 15.0000000000 16.0000000000
17.0000000000 18.0000000000 19.0000000000 20.0000000000
21.0000000000 22.0000000000 23.0000000000 24.0000000000
25.0000000000 26.0000000000 27.0000000000 28.0000000000
29.0000000000 30.0000000000 31.0000000000 32.0000000000
33.0000000000 34.0000000000 35.0000000000 36.0000000000
37.0000000000 38.0000000000 39.0000000000 40.0000000000
41.0000000000 42.0000000000 43.0000000000 44.0000000000
45.0000000000 46.0000000000 47.0000000000 48.0000000000
49.0000000000 50.0000000000 51.0000000000 52.0000000000
53.0000000000 54.0000000000 55.0000000000 56.0000000000
57.0000000000 58.0000000000 59.0000000000 60.0000000000
61.0000000000 62.0000000000 63.0000000000 64.0000000000
65.0000000000 66.0000000000 67.0000000000 68.0000000000
69.0000000000 70.0000000000 71.0000000000 72.0000000000
73.0000000000 74.0000000000 75.0000000000 76.0000000000
77.0000000000 78.0000000000 79.0000000000 80.0000000000
81.0000000000 82.0000000000 83.0000000000 84.0000000000
85.0000000000 86.0000000000 87.0000000000 88.0000000000
89.0000000000 90.0000000000 91.0000000000 92.0000000000
93.0000000000 94.0000000000 95.0000000000 96.0000000000
97.0000000000 98.0000000000 99.0000000000 100.000000000
This isn't a problem with the ACCESS used for the file (stream, sequential or direct) - it is a consequence of the format specification that you are using.
Note that you are not doing unformatted output. Formatted versus unformatted is a question of whether the output is intended to be human readable.
The star in the second specifier of the WRITE statement is a specification of list directed formatting. This means that the format used for the output is based on the list of things to be output. Beyond that and a small set of rules in the language for list directed output, you are pretty much leaving the appearance of things up to the Fortran processor (the compiler).
With list directed formatted output the processor is specifically allowed to insert as many records as it sees fit between items. It does that here, quite reasonably, in order to make it easier for people to read the file.
If you want more control over the appearance of your output, then use an explicit format. For example, something like:
write(unitout2,"(9999(G12.5,:,','))") bigArray
might be more appropriate.
(Technically when a sequential file is opened there is a processor defined maximum record length (in the absence of a programmer specified maximum length) that should not be exceeded. Practically, given the way sequential formatted files are stored on disk by nearly all current Fortran compilers, that technicality doesn't cause any problems.)

Fortran runtime error: Bad real number in item 1 of list input

I am getting run time error: Bad real number in item 1 of list input for this sample problem. Please, suggest the correct way.
implicit double precision (a-h,o-x)
parameter (ni=150)
dimension x(ni)
open(40,file='fortin')
do 80 i=1,5
read(40,*)x(i)
write(*,*)i,x(i)
80 continue
stop
end
The data in the fortin file arranged in column
1.0
5.0
3.0
5.0
7.0
Your code expects only numbers and it appears you have characters in the file. You can do one of two things to fix this:
Delete the words at the top of the fortin file
Add a single read(*,*) (no need for anything following it) before the loop
In my case, the problem lies in the data file, not the code.
My problem turn out to be the file is in Unicode format. When I view in vi, it's shown fine. But when I view in a viewer that does not support unicode, such as using midnight commander, it look like a mess. The one who sent me the file later told me that he save the file in UTF-16.

Applescript: Finding a track in a playlist by it's file system path

Can't pick a track from a playlist based on it's file system path (location). See below.
I put arrows before the result of each command.
In the first line, I successfully find the first track from the playlist "Testing" with genre "R&B".
Why doesn't the fourth line work ? It looks like I am doing the same as line 1 only searching by file-system location instead of by genre.
Is there another way to do this ?
tell application "iTunes"....
set t to first track of playlist "Testing" whose genre is "R&B"
--> file track id 18476 of user playlist id 18414 of source id 72 of application "iTunes"
set l to location of track 1 of playlist "Testing"
--> alias "Lion:Users:cworth:Desktop:a.mp3"
set f to POSIX file "/Users/cworth/Desktop/a.mp3" as alias
--> alias "Lion:Users:cworth:Desktop:a.mp3"
set tt to first track of playlist "Testing" whose location is f
--> error "iTunes got an error: A descriptor type mismatch occurred." number -10001 to item
...end tell
Studied up on Applescript and got it working with an explicit loop over the tracks: (see below)
A possible explanation for why the example above doesn't work is that the 'first track of playlist "Testing" whose location is...' returns a list of object specifiers (e.g. location of first track of playlist "Testing", etc.) instead of a list of actual locations - i.e. what's missing is the "get" command that returns the actual locations that you see inside the repeat loop below. That would explain the descriptor type mismatch, maybe ? I don't have the Applescript expertise or motivation to go any further, now that I've got it working, but I'm glad that it is!
tell application "iTunes"
set f to POSIX file "/Users/cworth/Music/04 It's A Man's, Man's, Man's World.mp3"
set a to f as alias
set z to missing value
repeat with tr in tracks of playlist "Testing"
set ll to get location of tr
if ll is a then set z to ll
end repeat
end tell
log z
Very belated reply. I believe the issue is that the track type does not have a location attribute, but the type file track does. Try searching the list of file track instances rather than all track instances:
tell application "Music"
set f to POSIX file "/Users/cworth/Music/04 It's A Man's, Man's, Man's World.mp3"
set res to first file track whose location is f
return res
end tell