Looking for an example of how to enhance this bit of code:
I’d like to accomplish the following but not sure how.
Is there a way to insert something to mylist so that when I enter another date the real estate that this long string of text spans across the page and it’s getting quite wide.
Is there a way to turn mylist into a dialogue prompt? So when I run the script it asks for the next date and the user just enters it and it will write to the text file when executed.
-- Example usage:
set myList to {"3/30/24 " & return, "4/6/24 " & return, "4/13/24 " & return, "4/18/24 " & return, "4/29/24 " & return, "5/4/24 " & return, "5/8/24 " & return, "5/13/24 " & return, "5/18/24 " & return, "5/25/24 " & return, "5/31/24 " & return, "6/8/24 " & return, "6/27/24 " & return, "7/6/24 " & return, "7/13/24 "}
-- Replace with your list of items
set outputFile to (path to desktop as text) & "July 1.txt" -- Replace with your desired output file path
I can’t seem to get my head around what you are asking.
First, why do you have the returns in every item in your list?
The 1st thing you listed was a run-on sentence that I couldn’t understand what you wanted.
Give an example.
This script that I have is used to track how many times a particular item gets completed. Let’s say getting a haircut; I learn better by using practical examples.
I had several of these scripts that write to text files and I wanted to see if I could get it to work, which it does.
I can keep adding dates to the list but as I mentioned, the list of dates is getting long and I know there’s a better way, thus my post.
Here’s my example:
on countAndWriteToFile(itemList, outputPath)
set itemCount to count of itemList
-- Convert the item count to text
set itemCountText to itemCount as text
set Cost to itemCount * 17.0 as text
-- Write the item count to the specified file
try
set fileDescriptor to open for access outputPath with write permission
write "Data generated by Haircut Counter Handler on " & (current date) & linefeed & linefeed & "Total haircuts in 2024 = " & itemCountText & linefeed & "Total Cost for haircuts in 2014 is = " & Cost & return & return & "2024 Haircut Dates" & return & return & itemList to fileDescriptor
close access fileDescriptor
display dialog "Item count has been written to the file." buttons {"OK"} default button "OK"
on error errMsg
close access fileDescriptor
display dialog "An error occurred: " & errMsg buttons {"OK"} default button "OK"
end try
end countAndWriteToFile
-- Example usage:
set myList to {"Jan 30 " & return, "Mar 5 " & return, "Apr 9 " & return, "Apr 15 " & return, "May 7 " & return, "June 4 " & return, "Jul 2 "}
-- Replace with your list of items
set outputFile to (path to desktop as text) & "Haircuts.txt" -- Replace with your desired output file path
countAndWriteToFile(myList, outputFile)
Another issue I see is the mixing of line endings, i.e. returns & linefeeds.
Use one or the other, not both.
Also, what do you do with this file once it’s generated? Do you read it with a text editor, or do you parse it with another script?
Here is a cleaned up version of yours…
on countAndWriteToFile(itemList, outputPath)
local itemCount, Cost, fileDescriptor, msg, tid
set tid to text item delimiters
set itemCount to count itemList
set Cost to itemCount * 17.0
set text item delimiters to linefeed
-- Write the item count to the specified file
try
set fileDescriptor to open for access outputPath with write permission
set eof fileDescriptor to 0
write "Data generated by Haircut Counter Handler on " & (current date) & linefeed & linefeed & "Total haircuts in 2024 = " & (itemCount as text) & linefeed & "Total Cost for haircuts in 2014 is = $" & Cost & linefeed & linefeed & "2024 Haircut Dates" & linefeed & linefeed & (itemList as text) to fileDescriptor
set msg to (itemCount as text) & " items have been written to the file."
on error errMsg
set msg to "An error occurred: " & errMsg
end try
try
close access fileDescriptor
end try
display alert msg giving up after 5
set text item delimiters to tid
end countAndWriteToFile
-- Example usage:
set myList to {"Jan 30", "Mar 5", "Apr 9", "Apr 15", "May 7", "June 4", "Jul 2"}
-- Replace with your list of items
set outputFile to (path to desktop as text) & "Haircuts.txt" -- Replace with your desired output file path
countAndWriteToFile(myList, outputFile)
It just writes to a text file, so when I add to it, I add another date and run the script. The script does what I want but I’d like to make it more efficient and use a dialog or something. Here’s an example of text file:
Data generated by Haircut Counter Handler on Thursday, July 4, 2024 at 7:10:50?AM
Total haircuts in 2024 = 7
Total Cost for haircuts in 2014 is = 119.0
Since you are writing the dates to a log file, you can just store them there instead of in the script. In your example they are the last items, so if you need them somewhere else they can be read from the file.
Here is a quick example of the text file being re-read to get the list of dates…
property outputPath : (path to desktop as text) & "Haircuts.txt"
on run
local myList, myAns, flag, mn, dy, msg
-- Example usage:
set myList to getItemList()
if class of myList is boolean then return
set flag to false
set msg to "Enter a date for a haircut"
repeat until flag
set myAns to display dialog msg default answer "" with title "Haircut Dates"
if button returned of myAns = "OK" then set myAns to text returned of myAns
if (count of words of myAns) = 2 then
set mn to word 1 of myAns
if mn is in "JanFebMarAprMayJunJulAugSepOctNovDec" then
set dy to word 2 of myAns
try
set dy to dy as integer
if dy ≤ 31 then
set flag to true
exit repeat
end if
end try
end if
end if
set msg to "Date was in incorrect format!" & return & return & "Enter a date for a haircut"
end repeat
if flag then set end of myList to (mn & " " & dy)
countAndWriteToFile(myList)
return myList
end run
on countAndWriteToFile(itemList)
local itemCount, Cost, fileDescriptor, msg, tid
set tid to text item delimiters
set itemCount to count itemList
set Cost to itemCount * 17.0
set text item delimiters to linefeed
-- Write the item count to the specified file
try
set fileDescriptor to open for access outputPath with write permission
set eof fileDescriptor to 0
write "Data generated by Haircut Counter Handler on " & (current date) & linefeed & linefeed & "Total haircuts in 2024 = " & (itemCount as text) & linefeed & "Total Cost for haircuts in 2014 is = $" & Cost & linefeed & linefeed & "2024 Haircut Dates" & linefeed & linefeed & (itemList as text) to fileDescriptor
set msg to (itemCount as text) & " items have been written to the file."
on error errMsg
set msg to "An error occurred: " & errMsg
end try
try
close access fileDescriptor
end try
display alert msg giving up after 5
set text item delimiters to tid
end countAndWriteToFile
on getItemList()
local myData
try
set myData to read file outputPath
on error
return false
end try
set myData to items 8 thru -1 of paragraphs of myData
end getItemList
** Edit ** I edited mine to ask for a date to add to the list, but red_menace beat me to it
Here is another version. The following script reads the dates (it can be other text) from the last part of the log file and asks for a new entry. The input is then added to the list, which is written back to the log file - the list of dates is not kept in the script. I’ve split it up a little and made it more general-purpose so that it can be modified for other items.
property header : "Data generated by Haircut Counter" -- date suffix is added when written to a file
property object : {"haircut", "haircuts"} -- {singular, plural}
property cost : "17.00"
property logFile : (path to desktop as text) & "Haircuts 2024.txt"
property delimiter : linefeed & tab -- delimiting text at the beginning and between date items
on run -- example
set newDateList to addToList from logFile
set output to assembleText for newDateList
writeText from output into logFile
end run
to addToList from filePath -- get a list of dates from a file, adding a new entry at the end
try
tell (read file filePath) to set dateText to text ((my (offset of delimiter in it)) + (count delimiter)) thru -1
set {prevTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, delimiter}
tell text items of dateText
set {dateList, previous} to {it, {"Last entries:" & return} & it & return}
if (count it) > 5 then set previous to {"Last 5 entries:" & return} & items -5 thru -1 of it & return
end tell
set {previous, AppleScript's text item delimiters} to {previous as text, prevTID}
on error errmess -- no file?
log errmess
set dateList to {}
set previous to ""
end try
tell (current date) to set newDate to text 1 thru 3 of (its month as text) & space & its day
set end of dateList to text returned of (display dialog previous & "Enter date to add:" default answer newDate with title "Add Entry to Log")
return dateList
end addToList
to assembleText for itemList -- assemble text pieces for writing to a file
tell (current date) to set {theDate, theYear} to {it as text, its year}
tell theDate to set theDate to text 1 thru -4 & space & text -2 thru -1 -- fix Sonoma Narrow No-Break Space bug (English)
set itemCount to (count itemList)
set totalCost to "$" & (do shell script "echo \"" & itemCount * cost & "\" | awk '{printf(\"%.2f\", $1)}'") -- formatting
set {prevTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, delimiter}
set {itemListText, AppleScript's text item delimiters} to {itemList as text, prevTID}
set theText to header & " - last updated " & theDate & linefeed & linefeed & "The total number of " & item 2 of object & " in " & theYear & " is " & itemCount & return & "The total cost of " & item 2 of object & " in " & theYear & " is " & totalCost & linefeed & linefeed & theYear & " " & item 1 of object & " dates:" & delimiter & itemListText
return theText
end assembleText
to writeText from fileText into filePath -- write text to a file
try
set fileRef to open for access filePath with write permission
set eof fileRef to 0 -- overwrite
write fileText to fileRef
close access fileRef
display dialog "File " & quoted form of filePath & " has been updated." buttons {"OK"} default button "OK" giving up after 5
return true
on error errmess number errnum
try
close access fileRef
end try
display alert "Error " & errnum message errMsg buttons {"OK"} default button "OK"
return false
end try
end writeText