File open / read error

I want to select a text file of numbers and read it.

set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set inFile to open for access file TargetFile
set realRawDataSet to read inFile as number

I get the file selection box correctly After selecting “data.txt” I get
"Script error: Can’t make file (alias “MacAir:Users:JRW:Documents:Data.txt”) into type «class fsrf».

The highlighted text in my code is open for access file TargetFile.

The path is correct – my laptop has “MacAir” rather than “Macintosh HD” as the root.
Why is this happening?

Model: 13-inch Mac Air running Mojave
AppleScript: 2.7
Browser: Safari 605.1.15
Operating System: macOS 10.14

That error is telling you you are trying to coerce an alias into a file reference; TargetFile is an alias, so remove the word file before it.

But I doubt that reading a file “as number” is going to give you what you expect, if anything.

And don’t forget close access inFile when you’ve finished reading.

But in fact you don’t need to open the file for access if it already exists and you’re only reading it once. You can simply use the read command with the alias. The opening and closing will be taken care of automatically:

set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set realRawDataSet to (read TargetFile) --as number

Shane’s right about “as number”. It just returns a data object, eg. «data nmbr00003039». The “as” isn’t an AppleScript coercion here: it’s a parameter of read telling it how to understand the data in the file. AppleScript numbers are either integers or reals. There’s no way to write them to file in the vague form of “number”, so there’s no way read can interpret the data as such. It simply returns a data object with the label it’s been given and assumes the script will know what to do with it. If you’ve written an integer to the file, it must be read “as integer”. If you’ve written a real, it must be read “as real”. If you’ve written a text representation of either an integer or a real, you can read it as “string” (which is the default for read, not requiring an “as” parameter) and coerce the result to number:

set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set realRawDataSet to (read TargetFile) as number

Note the parentheses round the read command so that “as” is is understood not to be a parameter of it, but an AppleScript coercion.

This again will not give him what he needs. The read TargetFile command returns text as 1 single line. If there is at least 1 non-digital character in the text, then Applescript will refuse to coerce text to a numbers. Here you need to coerce text one character at a time, or one word at a time, or one paragraph at a time, depending on the content. In addition, the coercing command must be placed in a try block. Then AppleScript will only coerce something that can be coerced, and omit the rest stuff.



set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set my_Words to every word of (read TargetFile)
set numeric_List to {}
repeat with my_Word in my_Words
	try
		set my_Number to (my_Word as number)
		set end of numeric_List to my_Number
	end try
end repeat
numeric_List

It may not give him what he needs. None of us has any idea what’s in his file, so we can’t give any definitive code. It seems unlikely that he’d be trying to read or coerce the file’s contents to number if he thought they contained anything else. But who knows? :slight_smile:

But your code is undoubtedly helpful. Just be careful that a “word” is a rather vague concept in AppleScript. A lot depends on context and localisation. Numbers can have spaces in them in some languages and the minus sign “-” isn’t a word character on English-language systems.

The data set is file with these contents:

14 9.5 22 22.3 6. 16 30 31 11 20 17 17.5 9 25 19 22 24 28.3 20.6 19.1 22 11 22 22

Alternatively, I have the integer data to test:

A set of real numbers, as you can see. Considering Mr. Garvey’s post, it has periods and spaces. Ideally, the program should work on both real and integer data.

I ran this code with integer data as follows:
14 9 22 22 6 16 30 31 11 20 17 17 9 25 19 22 24 28 20 19 22 11 22 22

set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set my_Words to every word of (read TargetFile)
set numeric_List to {}
repeat with my_Word in my_Words
	try
		set my_Number to (my_Word as number)
		set end of numeric_List to my_Number
	end try
end repeat
property SortedAlready : false
property Temp : missing value
property Finish : missing value
copy numeric_List to realWorkingDataSet
display dialog realWorkingDataSet

and for the display dialog line I got “41” – this is neither the size or sum of the data set. I don’t know where it appeared. When In ran the code on the real data, I got “End of file error.”

When I run

set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set inFile to open for access TargetFile
set realRawDataSet to (read inFile)
display dialog realRawDataSet

with raw data the display dialog line gives me the correct set. With integer data, I get 41 again/

The code below the input section computes varies values, including statistical measures of central tendency. It runs correctly when I include the dataset as a variable. Things only blow up when I try to read the data from a file.

Ideally, the code should run on both real and integer data.

That’s not very helpful, I’m afraid. Does the file contain the text “14 9.5 22 22.3 6. 16 30 31 11 20 17 17.5 9 25 19 22 24 28.3 20.6 19.1 22 11 22 22”? If so, how is it encoded? MacRoman? UTF-8? UTF-16?

Or does it contain the list {14, 9.5, 22, 22.3, 6.0, 16, 30, 31, 11, 20, 17, 17.5, 9, 25, 19, 22, 24, 28.3, 20.6, 19.1, 22, 11, 22, 22}?

Or does it contain the integer 14, the real 9.5, the integer 22, … etc. written to the file sequentially?

It matters because the script has to interpret the data in the correct way to produce the correct result. By the way, what is the result you want?

KniazidisR’s script is based on the assumption that the data in your file is UTF-8 or MacRoman text representing a sequence of numbers and that you want to read that text and derive from it a list of actual integers and reals. The result is a list. If you try to use display dialog on it, you should be getting an error, not “41”.

That’s indicating a problem at the read stage, probably caused by your own script not containing a close access statement. Script Editor will now have several access channels open to the file, all of which have been used to read it through to the end. KniazidisR’s script and/or mine may be trying to use one of these. The best cure would be to correct your script, save your current work, quit Script Editor to surrender the channels, and then reopen it.

Here, with a text file containing :
[format]14 9.5 22 22.3 6. 16 30 31 11 20 17 17.5 9 25 19 22 24 28.3 20.6 19.1 22 11 22 22[/format]

the script return:
{14, 22, 6, 16, 30, 31, 11, 20, 17, 9, 25, 19, 22, 24, 22, 11, 22, 22}

which is normal because here the word “9.5” can’t be coerced as number.

I edited the script as :

property SortedAlready : false
property Temp : missing value
property Finish : missing value


set deciSep to character 2 of (0.5 as text) # get the local decimal delimiter
set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)

set theText to read targetFile
if deciSep is not "." then set theText to my remplace(theText, ".", deciSep)
set my_Words to every word of theText
log my_Words
set numeric_List to {}
repeat with my_Word in my_Words
	try
		set my_Number to (my_Word as number)
		set end of numeric_List to my_Number
	end try
end repeat

numeric_List
(*
copy numeric_List to realWorkingDataSet
display dialog realWorkingDataSet
*)


#=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d1}
	set l to text items of t
	set AppleScript's text item delimiters to d2
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end remplace

#=====

and now, the script return the complete list of numbers.

{14, 9.5, 22, 22.3, 6, 16, 30, 31, 11, 20, 17, 17.5, 9, 25, 19, 22, 24, 28.3, 20.6, 19.1, 22, 11, 22, 22}

With the code used by JRWoodward, there is no need to close something.
This command is required if we use open for access which is not the case here.

Yvan KOENIG (VALLAURIS, France) dimanche 7 avril 2019 12:26:24

In an AppleScript, command as number is equivalent to command as integer. Therefore, I correct my script. It should be like this (is checked: it works):



set TargetFile to choose file of type "txt" with prompt "Select input file: " default location (path to documents folder)
set my_Words to every word of (read TargetFile)
set numeric_List to {}
repeat with my_Word in my_Words
	try
		set my_Number to (my_Word as real)
		if not (my_Word contains ".") then set my_Number to (my_Word as integer)
		set end of numeric_List to my_Number
	end try
end repeat

Here, with a text file containing :
“14 9.5 22 22.3 6. 16 30 31 11 20 17 17.5 9 25 19 22 24 28.3 20.6 19.1 22 11 22 22”
(Note: don’t enter quotes in the text editor)

the script return:
{14, 9.5, 22, 22.3, 6, 16, 30, 31, 11, 20, 17, 17.5, 9, 25, 19, 22, 24, 28.3, 20.6, 19.1, 22, 11, 22, 22}

NOTE: If your script fails again, then paste that code line to beginning of script:
set AppleScript’s text item delimiters to “”

OK, I delete this script from my Script Editor. It bored me, and it’s time to take a shower too.