I premise I've read many questions about this problem but I cannot solve it.
During the reading of my .csv file I get the following error:
forrtl: severe (59): list-directed I/O syntax error, unit 10, file D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits - TEST\InputFiles\test_Ast.csv. It seems to be produced by a specific line of my .csv file attached beloew (the last one).
Here is my .CSV file:
"pdes","name","epoch","a","e","i","om","w","ma","q","ad"
1580,Betulia,2459600.5,2.197288160959855,.4871550690589618,52.07925829047207,62.2921305585828,159.5134530240992,16.62891169416756,1.126868095165017,3.267708226754692
1620,Geographos,2459600.5,1.245689288381319,.3353623816094239,13.33753650294321,337.1849253204765,276.9463790166408,300.4925456829043,.8279319618844114,1.663446614878227
1627,Ivar,2459600.5,1.86327342970777,.3967369932313492,8.451956512766827,133.120308337423,167.8035837640704,129.0289785125129,1.124043931637646,2.602502927777894
1685,Toro,2459600.5,1.367465568905196,.435966790549019,9.382739662870495,274.2362441040706,127.2114688956593,300.0617970060148,.7712959936433091,1.963635144167082
1862,Apollo,2459600.5,1.470502475713431,.5600430467767759,6.353083928279622,35.56898244993719,286.0386669340027,60.20237527657879,.6469577889220891,2.294047162504772
1863,Antinous,2459600.5,2.25922922966352,.6059920366929147,18.39886422664638,346.4237098245764,268.0896471241496,244.0101430178307,.8901543074235589,3.628304151903481
1864,Daedalus,2459600.5,1.460979692497998,.6144866009907846,22.21536437289675,6.613194571694206,325.6563726287792,196.1166696228387,.5632272471383416,2.358732137857654
1865,Cerberus,2459600.5,1.079986459127503,.4669721847798676,16.09858904525619,212.8963846822369,325.2653260753237,170.2073771841984,.57566282277606,1.584310095478947
1866,Sisyphus,2459600.5,1.893353802479725,.5383695942642949,41.20637430558688,63.47259682927852,293.0824330786623,331.1476239661798,.8740296840399557,2.912677920919495
1915,Quetzalcoatl,2459600.5,2.543790754476287,.5706410666538692,20.40472660837776,162.9348721741076,347.8091351438147,41.39145147165023,1.092199284997688,3.995382223954886
1916,Boreas,2459600.5,2.272324177667199,.4498393843780145,12.88297395642586,340.5981620510102,335.9167764123868,352.2401366045371,1.250143268478108,3.294505086856289
1917,Cuyo,2459600.5,2.14981121226236,.5054666607865446,23.95922692157032,188.2869783127825,194.5115030151171,82.2843922810623,1.063153317478631,3.236469107046088
1943,Anteros,2459600.5,1.430366783173011,.2560374828122278,8.706034969532251,246.3110706020363,338.3801329232052,173.8814283992249,1.064139272511169,1.796594293834852
1980,Tezcatlipoca,2459600.5,1.709370985747121,.3648359123967504,26.8689695764886,246.560199388918,115.4661353995156,314.1597421163634,1.085731062537538,2.333010908956705
1981,Midas,2459600.5,1.776435963774881,.6501354173857774,39.82986428861084,356.8569898560586,267.8286153975083,202.5329806814936,.621512027006993,2.931359900542769
2059,Baboquivari,2459600.5,2.64324121274608,.531432311471031,11.02055447003622,200.6851159860844,192.4190577597405,181.8930083473287,1.23853742528094,4.04794500021122
2061,Anza,2459600.5,2.264279343476608,.5360981217114927,3.800349706160866,207.3741353983842,157.0286649770264,354.1526556258232,1.050403440408666,3.478155246544549
2062,,2459600.5,.9669087478156669,.1827720931291991,18.9345273941421,108.5428491298942,148.0586126391113,21.46549438015371,.7901848121124645,1.143632683518869
"1979 XB",,2444221.5,2.228085656329666,.7084495059291489,24.73412122397795,86.0555030947377,75.57989828051527,346.3183743701075,.6495994739350907,3.806571838724241
594913,'Aylo'chaxnim,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162
Here is my Fortran program (it contains a main file and some modules):
program Main_NEOs_orbits_TEST
use DataType
use Constants
use DataHandling
implicit none
! Declarations
character*100 :: input_path,output_path_ast_EM_loc, input_filename_ast,input_filename_cmt, output_path, output_filename_ast
character*118 :: str_line
character*2 :: str_name
character*30, dimension (3) :: str_output
integer :: i,j,iflag, no_data_lines1,n_lines2, iReturn, num_orb_elem
type(NEO), dimension (:), allocatable :: Ast_data
! Definition of constants, paths names and file names
input_path = 'D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits - TEST\InputFiles\'
input_filename_ast = 'test_Ast.csv'
! Reading of asteroids data
call read_NEOs_data(iu_in1, input_path, input_filename_ast, no_data_lines1, Ast_data)
stop
end program Main_NEOs_orbits_TEST
**********************************************************************************************************************************************
module Constants
use DataType
implicit none
real(pr), parameter :: ZERO = 0.0_pr, ONE = 1.0_pr, TWO = 2.0_pr, THREE = 3.0_pr, FOUR = 4.0_pr, SEVEN = 7.0_pr
real(pr), parameter :: HALF = 0.5_pr, QUART = 0.25_pr
real(pr), parameter :: DAY = 86400.0_pr, YEAR = 365.25_pr*DAY, CENTURY = 36525.0_pr
real(pr), parameter :: KILO = 1000.0_pr
real(pr), parameter :: AU2Km = 149597870.700_pr ! (from Astronomicals Unit to kilometers)
real(pr), parameter :: tol = 1.e-9_pr
real(pr), parameter :: xmu = 1.32712440018e11_pr ! (km^3 * s^-2) xmu = G * M_Sun https://ssd.jpl.nasa.gov/astro_par.html
! Unit number for files
integer :: iu_in1 = 10 !input file
integer :: iu_in2 = 11 !input file
integer :: iu_out1 = 12 !output file
integer :: iu_out2 = 13 !output file
end module Constants
**********************************************************************************************************************************************
module DataHandling
use DataType
implicit none
contains
!***********************************************************************
subroutine read_NEOs_data(UnitNum, FilePath, FileName, DataLinesNum, NEOs_data)
!***********************************************************************
! Subroutine for reading of asteroids database
!***********************************************************************
! INPUT:
!
! OUTPUT:
!***********************************************************************
implicit none
! Arguments
integer, intent (in) :: UnitNum
character (len=*), intent (in) :: FilePath
character (len=*), intent (in) :: FileName
integer, intent (out) :: DataLinesNum
type(NEO), dimension (:), allocatable, intent(out) :: NEOs_data
!Local variables
integer :: i, iflag
open(unit = UnitNum, file = trim(FilePath) // trim(FileName), status='old', &
access = 'sequential',form = 'formatted', action='read')
! Count lines
DataLinesNum = 0
read(UnitNum,*) ! Header line
do
read(UnitNum,*,iostat = iflag)
if (iflag/=0) exit
DataLinesNum = DataLinesNum + 1
enddo
rewind(UnitNum)
! Variables allocation
allocate(NEOs_data(DataLinesNum))
! Data reading
read(UnitNum,*) ! skip header line (variables names will be assigned again)
do i = 1, DataLinesNum
read(UnitNum,*) NEOs_data(i)
enddo
close(unit = UnitNum, status='keep')
return
end subroutine read_NEOs_data
!***********************************************************************
end module DataHandling
**********************************************************************************************************************************************
module DataType
implicit none
integer, parameter :: pr = selected_real_kind (p = 15) ! original value (p = 14)
!"NEO" data type declaration
type NEO ! NEOs data :
character*20 :: pdes ! pdes Object primary designation
character*20 :: name ! IAU name Object IAU name
real(pr) :: epoch ! Epoch Epoch Julian Date (TDB)
real(pr) :: a ! a Semi-major axis (au)
real(pr) :: e ! e Eccentricity
real(pr) :: i ! i Inclination w.r.t. xy-plane (deg)
real(pr) :: om ! om Longitude of Ascending Node (deg)
real(pr) :: w ! w Argument of Perihelion wrt to ecliptic/equinox (deg)
real(pr) :: ma ! ma Mean anomaly (deg)
real(pr) :: q ! q Perihelion distance (au)
real(pr) :: ad ! ad Aphelion distance (au)
end type NEO
end module DataType
I need to mantain the format of the .csv file, so I cannot modify it.
Can you explain me why the line:
594913,'Aylo'i ,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162 produces the above said error?
Error output:
forrtl: severe (59): list-directed I/O syntax error, unit 10, file D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits - TEST\InputFiles\test_Ast.csv
Image PC Routine Line Source
libifcoremdd.dll 00007FFE5DBBAA5D Unknown Unknown Unknown
libifcoremdd.dll 00007FFE5DC1B6FC Unknown Unknown Unknown
NEOs_orbits_TEST. 00007FF75BB41B9B DATAHANDLING_mp_R 53 DataHandling.f90
NEOs_orbits_TEST. 00007FF75BB43072 MAIN__ 57 Main_NEOs_orbits_TEST.f90
NEOs_orbits_TEST. 00007FF75BB4332E Unknown Unknown Unknown
NEOs_orbits_TEST. 00007FF75BB45F69 Unknown Unknown Unknown
NEOs_orbits_TEST. 00007FF75BB45E8E Unknown Unknown Unknown
NEOs_orbits_TEST. 00007FF75BB45D4E Unknown Unknown Unknown
NEOs_orbits_TEST. 00007FF75BB45FDE Unknown Unknown Unknown
KERNEL32.DLL 00007FFF269C7034 Unknown Unknown Unknown
ntdll.dll 00007FFF288A2651 Unknown Unknown Unknown
line 53: read(UnitNum,*) NEOs_data(i)
line 57: call read_NEOs_data(iu_in1, input_path, input_filename_ast, no_data_lines1, Ast_data)
Problematic line: 594913,'Aylo'chaxnim,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162
Vladimir explains why you can not use list directed input for this, due to the unfortunate use of inverted commas. Here is a simple version of how I might go about addressing this problem, were I doing it properly I would package things up in modules a bit more carefully:
ijb#LAPTOP-GUG8KQ9I:~/work/stack$ cat csv.f90
Module split_string_module
Type, Public :: split_string_token
Character( Len = : ), Allocatable, Public :: token
End type split_string_token
Public :: split_string
Private
Contains
Pure Subroutine split_string( separators, string, tokens )
! Split a string given the separators into an array of tokens
Implicit None
Character( Len = * ) , Intent( In ) :: separators
Character( Len = * ) , Intent( In ) :: string
Type( split_string_token ), Dimension( : ), Allocatable, Intent( Out ) :: tokens
Type( split_string_token ) :: new_token
Character( Len = : ), Allocatable :: current
Integer :: split_point
Allocate( tokens( 1:0 ) )
current = string
! While we have some characters
Do While( Len( current ) > 0 )
! Find the first separator
split_point = Scan( current, separators )
If( split_point /= 0 ) Then
! We have a separator - split the string at that point
new_token%token = current( 1:split_point - 1 )
! Catch the case of the last character in the string being a separator
If( split_point + 1 <= Len( current ) ) Then
current = current( split_point + 1: )
Else
current = ''
End If
Else
! No separator found, so the remainder of the string is a token
new_token%token = current
current = ''
End If
! Add the token to the list
tokens = [ tokens, new_token ]
End Do
End Subroutine split_string
End Module split_string_module
Module read_csv_module
Public :: read_csv_line
Private
Contains
Subroutine read_csv_line( unit, tokens, error )
! Read a line and split it into an array of comma separated tokens
Use split_string_module, Only : split_string_token, split_string
Implicit None
Integer , Intent( In ) :: unit
Type( split_string_token ), Dimension( : ), Allocatable, Intent( Out ) :: tokens
Integer , Intent( Out ) :: error
Integer, Parameter :: max_line_length = 4096
Character( Len = max_line_length ) :: line
Read( unit, '( a )', iostat = error ) line
If( error == 0 ) Then
Call split_string( ',', Trim( line ), tokens )
End If
End Subroutine read_csv_line
End Module read_csv_module
Program testit
Use read_csv_module , Only : read_csv_line
Use split_string_module, Only : split_string_token
Type( split_string_token ), Dimension( : ), Allocatable :: tokens
Integer :: unit
Integer :: error
Integer :: i
Open( newunit = unit, file = 'input.dat' )
error = 0
Do While( error == 0 )
Call read_csv_line( unit, tokens, error )
If( error == 0 ) Then
Do i = 1, Size( tokens )
Write( *, '( a, 3x )', Advance = 'No' ) Trim( tokens( i )%token )
End Do
Write( *, * )
End If
End Do
Close( unit )
End Program testit
ijb#LAPTOP-GUG8KQ9I:~/work/stack$ gfortran-10 --version
GNU Fortran (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb#LAPTOP-GUG8KQ9I:~/work/stack$ gfortran-10 -Wall -Wextra -Wuse-without-only -Werror -fcheck=all -std=f2008 -g -O csv.f90
ijb#LAPTOP-GUG8KQ9I:~/work/stack$ cat input.dat
"pdes","name","epoch","a","e","i","om","w","ma","q","ad"
1580,Betulia,2459600.5,2.197288160959855,.4871550690589618,52.07925829047207,62.2921305585828,159.5134530240992,16.62891169416756,1.126868095165017,3.267708226754692
1620,Geographos,2459600.5,1.245689288381319,.3353623816094239,13.33753650294321,337.1849253204765,276.9463790166408,300.4925456829043,.8279319618844114,1.663446614878227
1627,Ivar,2459600.5,1.86327342970777,.3967369932313492,8.451956512766827,133.120308337423,167.8035837640704,129.0289785125129,1.124043931637646,2.602502927777894
1685,Toro,2459600.5,1.367465568905196,.435966790549019,9.382739662870495,274.2362441040706,127.2114688956593,300.0617970060148,.7712959936433091,1.963635144167082
1862,Apollo,2459600.5,1.470502475713431,.5600430467767759,6.353083928279622,35.56898244993719,286.0386669340027,60.20237527657879,.6469577889220891,2.294047162504772
1863,Antinous,2459600.5,2.25922922966352,.6059920366929147,18.39886422664638,346.4237098245764,268.0896471241496,244.0101430178307,.8901543074235589,3.628304151903481
1864,Daedalus,2459600.5,1.460979692497998,.6144866009907846,22.21536437289675,6.613194571694206,325.6563726287792,196.1166696228387,.5632272471383416,2.358732137857654
1865,Cerberus,2459600.5,1.079986459127503,.4669721847798676,16.09858904525619,212.8963846822369,325.2653260753237,170.2073771841984,.57566282277606,1.584310095478947
1866,Sisyphus,2459600.5,1.893353802479725,.5383695942642949,41.20637430558688,63.47259682927852,293.0824330786623,331.1476239661798,.8740296840399557,2.912677920919495
1915,Quetzalcoatl,2459600.5,2.543790754476287,.5706410666538692,20.40472660837776,162.9348721741076,347.8091351438147,41.39145147165023,1.092199284997688,3.995382223954886
1916,Boreas,2459600.5,2.272324177667199,.4498393843780145,12.88297395642586,340.5981620510102,335.9167764123868,352.2401366045371,1.250143268478108,3.294505086856289
1917,Cuyo,2459600.5,2.14981121226236,.5054666607865446,23.95922692157032,188.2869783127825,194.5115030151171,82.2843922810623,1.063153317478631,3.236469107046088
1943,Anteros,2459600.5,1.430366783173011,.2560374828122278,8.706034969532251,246.3110706020363,338.3801329232052,173.8814283992249,1.064139272511169,1.796594293834852
1980,Tezcatlipoca,2459600.5,1.709370985747121,.3648359123967504,26.8689695764886,246.560199388918,115.4661353995156,314.1597421163634,1.085731062537538,2.333010908956705
1981,Midas,2459600.5,1.776435963774881,.6501354173857774,39.82986428861084,356.8569898560586,267.8286153975083,202.5329806814936,.621512027006993,2.931359900542769
2059,Baboquivari,2459600.5,2.64324121274608,.531432311471031,11.02055447003622,200.6851159860844,192.4190577597405,181.8930083473287,1.23853742528094,4.04794500021122
2061,Anza,2459600.5,2.264279343476608,.5360981217114927,3.800349706160866,207.3741353983842,157.0286649770264,354.1526556258232,1.050403440408666,3.478155246544549
2062,,2459600.5,.9669087478156669,.1827720931291991,18.9345273941421,108.5428491298942,148.0586126391113,21.46549438015371,.7901848121124645,1.143632683518869
"1979 XB",,2444221.5,2.228085656329666,.7084495059291489,24.73412122397795,86.0555030947377,75.57989828051527,346.3183743701075,.6495994739350907,3.806571838724241
594913,'Aylo'chaxnim,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162
ijb#LAPTOP-GUG8KQ9I:~/work/stack$ ./a.out
"pdes" "name" "epoch" "a" "e" "i" "om" "w" "ma" "q" "ad"
1580 Betulia 2459600.5 2.197288160959855 .4871550690589618 52.07925829047207 62.2921305585828 159.5134530240992 16.62891169416756 1.126868095165017 3.267708226754692
1620 Geographos 2459600.5 1.245689288381319 .3353623816094239 13.33753650294321 337.1849253204765 276.9463790166408 300.4925456829043 .8279319618844114 1.663446614878227
1627 Ivar 2459600.5 1.86327342970777 .3967369932313492 8.451956512766827 133.120308337423 167.8035837640704 129.0289785125129 1.124043931637646 2.602502927777894
1685 Toro 2459600.5 1.367465568905196 .435966790549019 9.382739662870495 274.2362441040706 127.2114688956593 300.0617970060148 .7712959936433091 1.963635144167082
1862 Apollo 2459600.5 1.470502475713431 .5600430467767759 6.353083928279622 35.56898244993719 286.0386669340027 60.20237527657879 .6469577889220891 2.294047162504772
1863 Antinous 2459600.5 2.25922922966352 .6059920366929147 18.39886422664638 346.4237098245764 268.0896471241496 244.0101430178307 .8901543074235589 3.628304151903481
1864 Daedalus 2459600.5 1.460979692497998 .6144866009907846 22.21536437289675 6.613194571694206 325.6563726287792 196.1166696228387 .5632272471383416 2.358732137857654
1865 Cerberus 2459600.5 1.079986459127503 .4669721847798676 16.09858904525619 212.8963846822369 325.2653260753237 170.2073771841984 .57566282277606 1.584310095478947
1866 Sisyphus 2459600.5 1.893353802479725 .5383695942642949 41.20637430558688 63.47259682927852 293.0824330786623 331.1476239661798 .8740296840399557 2.912677920919495
1915 Quetzalcoatl 2459600.5 2.543790754476287 .5706410666538692 20.40472660837776 162.9348721741076 347.8091351438147 41.39145147165023 1.092199284997688 3.995382223954886
1916 Boreas 2459600.5 2.272324177667199 .4498393843780145 12.88297395642586 340.5981620510102 335.9167764123868 352.2401366045371 1.250143268478108 3.294505086856289
1917 Cuyo 2459600.5 2.14981121226236 .5054666607865446 23.95922692157032 188.2869783127825 194.5115030151171 82.2843922810623 1.063153317478631 3.236469107046088
1943 Anteros 2459600.5 1.430366783173011 .2560374828122278 8.706034969532251 246.3110706020363 338.3801329232052 173.8814283992249 1.064139272511169 1.796594293834852
1980 Tezcatlipoca 2459600.5 1.709370985747121 .3648359123967504 26.8689695764886 246.560199388918 115.4661353995156 314.1597421163634 1.085731062537538 2.333010908956705
1981 Midas 2459600.5 1.776435963774881 .6501354173857774 39.82986428861084 356.8569898560586 267.8286153975083 202.5329806814936 .621512027006993 2.931359900542769
2059 Baboquivari 2459600.5 2.64324121274608 .531432311471031 11.02055447003622 200.6851159860844 192.4190577597405 181.8930083473287 1.23853742528094 4.04794500021122
2061 Anza 2459600.5 2.264279343476608 .5360981217114927 3.800349706160866 207.3741353983842 157.0286649770264 354.1526556258232 1.050403440408666 3.478155246544549
2062 2459600.5 .9669087478156669 .1827720931291991 18.9345273941421 108.5428491298942 148.0586126391113 21.46549438015371 .7901848121124645 1.143632683518869
"1979 XB" 2444221.5 2.228085656329666 .7084495059291489 24.73412122397795 86.0555030947377 75.57989828051527 346.3183743701075 .6495994739350907 3.806571838724241
594913 'Aylo'chaxnim 2459600.5 .5554326489245599 .1770230892406738 15.86839958719851 6.704982245275168 187.3289626591178 211.0111749229703 .4571082455468037 .6537570523023162
ijb#LAPTOP-GUG8KQ9I:~/work/stack$
The list directed format is quite convenient, but at the same time quite complicated.
In this case you are reading something that starts with an apostrophe, contains another apostrophe and hence looks like an apostrophe-delimited sequence. In apostrophe-delimited character sequences the apostrophes are delimiters and are not considered to be a part of the string. However, this 'Aylo'chaxnim is then invalid because it has another stray characters after the delimiting apostrophe. If you need to parse this, you will need some custom parser and not the generic list-directed format.
Another option is consider this 'Aylo'chaxnim to be invalid (probably entered by the data provider by mistake) and remove it before giving it to your program. either manually, if it happens only as an exception, or by some pre-processing script.
Note that if there are additional characters before the starting apostrophe, it is fine. In that case the internal apostrophes are not interpreted as delimiters, but as normal characters in the character string.
As Ian Bush shown, the name is a legitimate asteroid name. So if you need to read the correct name 'Aylo'chaxnim you will need to parse the line yourself. You can tokenize it by localizing the commas and then parse the individual tokens.
There are also CSV reader libraries available but you have to check that they are actually able to cope with this.
I have created a case class like this:
def case_class(): Unit = {
case class StockPrice(quarter : Byte,
stock : String,
date : String,
open : Double,
high : Double,
low : Double,
close : Double,
volume : Double,
percent_change_price : Double,
percent_change_volume_over_last_wk : Double,
previous_weeks_volume : Double,
next_weeks_open : Double,
next_weeks_close : Double,
percent_change_next_weeks_price : Double,
days_to_next_dividend : Double,
percent_return_next_dividend : Double
)
And I have thousands of line as Array of String like this:
1,AA,1/7/2011,$15.82,$16.72,$15.78,$16.42,239655616,3.79267,,,$16.71,$15.97,-4.42849,26,0.182704
1,AA,1/14/2011,$16.71,$16.71,$15.64,$15.97,242963398,-4.42849,1.380223028,239655616,$16.19,$15.79,-2.47066,19,0.187852
1,AA,1/21/2011,$16.19,$16.38,$15.60,$15.79,138428495,-2.47066,-43.02495926,242963398,$15.87,$16.13,1.63831,12,0.189994
1,AA,1/28/2011,$15.87,$16.63,$15.82,$16.13,151379173,1.63831,9.355500109,138428495,$16.18,$17.14,5.93325,5,0.185989
How Can I parse data from Array into that case class?
Thank you for your help!
You can proceed as below (I've taken simplified example)
Given your case class and data (lines)
// Your case-class
case class MyCaseClass(
fieldByte: Byte,
fieldString: String,
fieldDouble: Double
)
// input data
val lines: List[String] = List(
"1,AA,$1.1",
"2,BB,$2.2",
"3,CC,$3.3"
)
Note: you can read lines from a text file as
val lines = Source.fromFile("my_file.txt").getLines.toList
You can have some utility methods for mapping (cleaning & parsing)
// remove '$' symbols from string
def removeDollars(line: String): String = line.replaceAll("\\$", "")
// split string into tokens and
// convert into MyCaseClass object
def parseLine(line: String): MyCaseClass = {
val tokens: Seq[String] = line.split(",")
MyCaseClass(
fieldByte = tokens(0).toByte,
fieldString = tokens(1),
fieldDouble = tokens(2).toDouble
)
}
And then use them to convert strings into case-class objects
// conversion
val myCaseClassObjects: Seq[MyCaseClass] = lines.map(removeDollars).map(parseLine)
As a more advanced (and generalized) approach, you can generate the mapping (parsing) function for converting tokens into fields of your case-class using something like reflection, as told here
Here's one way of doing it. I'd recommend splitting everything you do up into lots of small, easy-to-manage functions, otherwise you will get lost trying to figure out where something is going wrong if it all starts throwing exceptions. Data setup:
val array = Array("1,AA,1/7/2011,$15.82,$16.72,$15.78,$16.42,239655616,3.79267,,,$16.71,$15.97,-4.42849,26,0.182704",
"1,AA,1/14/2011,$16.71,$16.71,$15.64,$15.97,242963398,-4.42849,1.380223028,239655616,$16.19,$15.79,-2.47066,19,0.187852",
"1,AA,1/21/2011,$16.19,$16.38,$15.60,$15.79,138428495,-2.47066,-43.02495926,242963398,$15.87,$16.13,1.63831,12,0.189994",
"1,AA,1/28/2011,$15.87,$16.63,$15.82,$16.13,151379173,1.63831,9.355500109,138428495,$16.18,$17.14,5.93325,5,0.185989")
case class StockPrice(quarter: Byte, stock: String, date: String, open: Double,
high: Double, low: Double, close: Double, volume: Double, percent_change_price: Double,
percent_change_volume_over_last_wk: Double, previous_weeks_volume: Double,
next_weeks_open: Double, next_weeks_close: Double, percent_change_next_weeks_price: Double,
days_to_next_dividend: Double, percent_return_next_dividend: Double
)
Function to turn Array[String] into Array[List[String]] and handle any empty fields (I've made an assumption here that you want empty fields to be 0. Change this as necessary):
def splitArray(arr: Array[String]): Array[List[String]] = {
arr.map(
_.replaceAll("\\$", "") // Remove $
.split(",") // Split by ,
.map {
case x if x.isEmpty => "0" // If empty
case y => y // If not empty
}
.toList
)
}
Function to turn a List[String] into a StockPrice. Note that this will fall over if the List isn't exactly 16 items long. I'll leave you to handle any of that. Also, the names are pretty non-descriptive so you can change that too. It will also fall over if your data doesn't map to the relevant .toDouble or toByte or whatever - you can handle this yourself too:
def toStockPrice: List[String] => StockPrice = {
case a :: b :: c :: d :: e :: f :: g :: h :: i :: j :: k :: l :: m :: n :: o :: p :: Nil =>
StockPrice(a.toByte, b, c, d.toDouble, e.toDouble, f.toDouble, g.toDouble, h.toDouble, i.toDouble, j.toDouble,
k.toDouble, l.toDouble, m.toDouble, n.toDouble, o.toDouble, p.toDouble)
}
A nice function to bring this all together:
def makeCaseClass(arr: Array[String]): Seq[StockPrice] = {
val splitArr: Array[List[String]] = splitArray(arr)
splitArr.map(toStockPrice)
}
Output:
println(makeCaseClass(array))
//ArraySeq(
// StockPrice(1,AA,1/7/2011,15.82,16.72,15.78,16.42,2.39655616E8,3.79267,0.0,0.0,16.71,15.97,-4.42849,26.0,0.182704),
// StockPrice(1,AA,1/14/2011,16.71,16.71,15.64,15.97,2.42963398E8,-4.42849,1.380223028,2.39655616E8,16.19,15.79,-2.47066,19.0,0.187852),
// StockPrice(1,AA,1/21/2011,16.19,16.38,15.6,15.79,1.38428495E8,-2.47066,-43.02495926,2.42963398E8,15.87,16.13,1.63831,12.0,0.189994),
// StockPrice(1,AA,1/28/2011,15.87,16.63,15.82,16.13,1.51379173E8,1.63831,9.355500109,1.38428495E8,16.18,17.14,5.93325,5.0,0.185989)
//)
Edit:
To explain the a :: b :: c ..... bit - this is a way of assigning names to items in a List or Seq, given you know the List's size.
val ls = List(1, 2, 3)
val a :: b :: c :: Nil = List(1, 2, 3)
println(a == ls.head) // true
println(b == ls(1)) // true
println(c == ls(2)) // true
Note that the Nil is important because it signifies the last element of the List being Nil. Without it, c would be equal to List(3) as the rest of any List is assigned to the last value in your definition.
You can use this in pattern matching as I have in order to do something with the results:
val ls = List(1, "b", true)
ls match {
case a :: b :: c if c == true => println("this will not be printed")
case a :: b :: c :: Nil if c == true => println(s"this will get printed because c == $c")
} // not exhaustive but you get the point
You can also use it if you know what you want each element in the List to be, like this:
val personCharacteristics = List("James", 26, "blue", 6, 85.4, "brown")
val name :: age :: eyeColour :: otherCharacteristics = personCharacteristics
println(s"Name: $name; Age: $age; Eye colour: $eyeColour")
// Name: James; Age: 26; Eye colour: blue
Obviously these examples are pretty trivial and not exactly what you'd see as a professional Scala developer (at least I don't), but it's a handy thing to be aware of as I do still use this :: syntax at work sometimes.
as stated above i am trying to get a vumat running, using allocatable arrays. I need to store and reuse the history of some values, therefore I tried allocatable arrays:
C
subroutine vumat(
C Read only -
1 nblock, ndir, nshr, nstatev, nfieldv, nprops, lanneal,
2 stepTime, totalTime, dt, cmname, coordMp, charLength,
3 props, density, strainInc, relSpinInc,
4 tempOld, stretchOld, defgradOld, fieldOld,
5 stressOld, stateOld, enerInternOld, enerInelasOld,
6 tempNew, stretchNew, defgradNew, fieldNew,
C Write only -
7 stressNew, stateNew, enerInternNew, enerInelasNew )
C
include 'vaba_param.inc'
#include <SMAAspUserSubroutines.hdr>
dimension props(nprops), density(nblock), coordMp(nblock,*),
1 charLength(nblock), strainInc(nblock,ndir+nshr),
2 relSpinInc(nblock,nshr), tempOld(nblock),
3 stretchOld(nblock,ndir+nshr),
4 defgradOld(nblock,ndir+nshr+nshr),
5 fieldOld(nblock,nfieldv), stressOld(nblock,ndir+nshr),
6 stateOld(nblock,nstatev), enerInternOld(nblock),
7 enerInelasOld(nblock), tempNew(nblock),
8 stretchNew(nblock,ndir+nshr),
8 defgradNew(nblock,ndir+nshr+nshr),
9 fieldNew(nblock,nfieldv),
1 stressNew(nblock,ndir+nshr), stateNew(nblock,nstatev),
2 enerInternNew(nblock), enerInelasNew(nblock)
c ID & Contents of lStatusArray
parameter ( j_iID_lStatusArray = 1)
parameter ( i_lStatusArray_Status = 1)
parameter ( n_lStatusArray_size = 1)
integer lStatusArray(n_lStatusArray_size)
pointer(ptrlStatusArray,lStatusArray)
print *,"huhu"
c************* this line causes the only error! *****************
ptrlStatusArray = SMALocalIntArrayAccess(j_iID_lStatusArray)
return
end
C
C
C ************************************************
C user routine to dynamically exchange data
Subroutine vexternaldb(lOp, i_Array, niArray, r_Array, nrArray)
*
include 'vaba_param.inc'
#include <SMAAspUserSubroutines.hdr>
dimension i_Array(niArray),
* r_Array(nrArray)
C possible values for argument lOp
parameter (j_int_startAnalysis = 0,
* j_int_startStep = 1,
* j_int_setupIncrement = 2,
* j_int_startIncrement = 3,
* j_int_endIncrement = 4,
* j_int_endStep = 5,
* j_int_endAnalysis = 6)
C contents of i_Array
parameter (
* i_int_nTotalNodes = 1,
* i_int_nTotalElements = 2,
* i_int_kStep = 3,
* i_int_kInc = 4,
* i_int_iStatus = 5,
* i_int_lWriteRestart = 6)
C possible values for i_Array(i_int_iStatus)
parameter (j_int_continue = 0,
* j_int_terminateStep = 1,
* j_int_terminateAnalysis = 2)
C contents of r_Array
parameter (
* i_flt_totalTime = 1,
* i_flt_stepTime = 2,
* i_flt_dTime = 3 )
c ID & Contents of lStatusArray
parameter ( j_iID_lStatusArray = 1)
parameter ( i_lStatusArray_Status = 1)
parameter ( n_lStatusArray_size = 1)
integer lStatusArray(n_lStatusArray_size)
pointer(ptrlStatusArray,lStatusArray)
*
if( lOp .eq. j_int_StartAnalysis) then
ptrlStatusArray = SMALocalIntArrayCreate(
* j_iID_lStatusArray, n_lStatusArray_size)
lStatusArray(i_lStatusArray_Status) = j_int_continue
end if
if( i_Array(i_int_iStatus) .eq. j_int_TerminateAnalysis .or.
* lOp .eq. j_int_endAnalysis) then
call SMALocalIntArrayDelete(j_iID_lStatusArray)
end if
*
* Skip writing restart frames to save on disk!
i_Array(i_int_lWriteRestart) = 0
*
return
end
C ************************************************
C
When I want to run the code, it works well without the marked line. Otherwise, if I want to get access to the array utilizing SMALocalIntArrayAccess, Abaqus crashes:
Abaqus JOB test
Abaqus 6.14-2
Begin Compiling Single Precision Abaqus/Explicit User Subroutines
12/8/2016 4:29:41 PM
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 17.0 Build 20160721
Copyright (C) 1985-2016 Intel Corporation. All rights reserved.
End Compiling Single Precision Abaqus/Explicit User Subroutines
Begin Linking Single Precision Abaqus/Explicit User Subroutines
Bibliothek "explicitU.lib" und Objekt "explicitU.exp" werden erstellt.
End Linking Single Precision Abaqus/Explicit User Subroutines
12/8/2016 4:29:41 PM
Begin Analysis Input File Processor
12/8/2016 4:29:41 PM
Run pre.exe
12/8/2016 4:29:42 PM
End Analysis Input File Processor
Begin Abaqus/Explicit Packager
12/8/2016 4:29:42 PM
Run package.exe
huhu
12/8/2016 4:29:42 PM
Abaqus Error: The executable package.exe
aborted with system error code 1073741819.
Please check the .dat, .msg, and .sta files for error messages if the files
exist. If there are no error messages and you cannot resolve the problem,
please run the command "abaqus job=support information=support" to report and
save your system information. Use the same command to run Abaqus that you
used when the problem occurred. Please contact your local Abaqus support
office and send them the input file, the file support.log which you just
created, the executable name, and the error code.
Abaqus/Analysis exited with errors
I have totally no idea what I can do now. I tried several machines aswell.