iConvert 5.3a

User avatar
rbytes
Posts: 1795
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

iConvert 5.3a

Post by rbytes » Tue Nov 27, 2018 6:04 pm

Version 5.3a fixes an issue where an error occurred if the Data folder did not exist. In that case, one is now created.
Version 5.3 added the Frequency category with 23 measures, and an improved system for storing user preferences.

A reminder to download the three attachments and put them at the same location as the program.

Code: Select all

/*
iConvert 5.3
by rbytes and Dutchman, November 2018
Converts measurements in many categories.
A collaborative international project.

V5.3a
- Data-folder created if not present
V5.3 
* by Dutchman
- Function Pref() added to handle "preferences".
  "preferences" replaces "viewstate1"
  Number of preferences is extended to 5
  • interactive mode
  • currency datetime mode
  • saved list selections of Currency, Inflation Euro and Inflation US dollar
  The preference data can be followed by text for explanation
- Additional functions: 
  • Pref$(t$,sep$) to extract the preference string with numbers and 'sep$'
  • PreSel$(p1,p2) to make a preselext string from list settings p1 and p2
  • Preselect(cat) presets p1 and p2 which are variable for preferred categories

* by rbytes
- Category "Frequency" added. Frequency is simply the speed of repetition. It
is ubiquitous in the universe, applying to light, sound, electricity, radio waves,
rotation, radioactivity, time and many other phenomena.

V5.2
Now 21 conversion categories.

* added by rbytes
- New category "Illuminance" - various measures of the
  amount of light falling on a surface.
- Help button and help browser added
- Settings lower switch added to set "Currency ID", eg. 
  when off (default), ID is year-month-date (yyyymmdd)  
  when on, ID is month-date-hour-minute (mmddhhmm)
- After Update, the last category selected before the Update is selected again, and
  the From and To lists are set to the first measure in the lists.
- Widened the category list to fit newest category names

* added by Dutchman
- "Inflation Euro" category added, containing data from 1996-2018
- "Inflation US dollar" category added, containing data from 1914-2018.
- Function "Ext(Cat$)" created.
  It contains constants and variables for handling external data.
  By a call to Ext(Cat$) the function Table() will load external data.
  The data from category 'Cat$' is then transferred to  Ext.<cat>Name$()
  and Ext.<cat>Val$() in which <cat> is an identifier for category,
- Extra data (above the standard 2 items) in the external data lines are stored
  in 'Table.Rest$' with semicolon as separator. Intended for future use. 
- External Data files moved to folder Data, including 'Ext.Preferences$' "viewstate1"
- Dir parameter added to function LatestFile()
- Program "make inflation tables.sb" developed to generate inflation data.
- Function NetStatus$() added for test internet connection
- Added T in date-time display according to ISO 8601

V5
- Currency start-up made failure-proof
  Downloaded data is stored in an html-file, eg. "currencies.html 20181118",
  where the final 8 characters represent the year, month and date
  If download fails then existing html-file is used
  If failure is complete then Currency category will display red "X" error
- Update begins with 'purging' older html-files.
  So maximum 2 most recent html-files (if date changed) will exist
- Update now reads the most recent html file and generates data in
  a second file named "currencies.table"
  Import currencies simplified via function Table()
- Data rearranged to 'Measure$','Value'
- file "currencies.table" will silently be created if not present.
- Improved iPhone compatibility
- Integrated UpdateCurrencies.functions
  See https://kibernetik.pro/forum/viewtopic.php?f=20&t=2272
- The project continues as a single integrated program.
- The Update Currencies program code is now in a subroutine labelled UpdateData
- Bug fixes
V4
- a Settings button (gear symbol), left of the other buttons. This opens a
  popup Settings window with a switch to set the view for Update Currencies V2.1
  when the switch is off, the currency exchange file is updated without 
  interactivity.
  when the switch is on, the file is updated interactively with the user.
- file "Data/viewstate1" stores the view setting.
- Fuel Economy category added by rbytes, November 2018
- Acceleration category added by rbytes
- Update button added to launch "Update currencies.sb" 
  for updating currency exchange rates
- Flow Rate category added by rbytes
- Angle category added by rbytes
- Energy transition category added by Dutchman
- Temperature category added by Dutchman
V3
- Currency category added by Dutchman
  DATA generated with "Update currencies.sb"
V2
- animation added to title
  (plays only once, at launch)
- measures added in most categories
- scientific notation is now used for
  results larger than 100,000,000 or
  smaller than .00000001
- added Horsepower (Metric) to
  Power category
- eliminated >>> button;
  calculation is now automatic
  when list selections or
  input values are changed.
- code efficiency improved
*/
OPTION BASE 1
SET ORIENTATION LANDSCAPE
OPTION SPRITE POS CENTRAL
OPTION TEXT POS CENTRAL
SET BUTTONS CUSTOM
SET TOOLBAR OFF
laun$=LAUNCHER$()
GET SCREEN SIZE sw,sh

' set to 1 to test iPhone layout on iPad
iostest=0
IF iostest THEN
  sw=568
  sh=320
ENDIF
rw=sw/1024!rh=sh/740

'b'========= Constants ===================
''
Tscale$="Temperature"
CALL Ext("none") ' initiate external Id's

'' *** Note - IP address may change if router is rebooted ***
'  run ipconfig on your PC to find its IP address.

URL$="192.170.61.43"   ' example of IP address
DIM h$(2)


' each line of a file sent to a PC print server must end with these characters:

cr$=CHR$(13)       ' carriage return character
lf$=CHR$(10)       ' line feed character
gosub helpset

'   Currency Data initialisation

GRAPHICS
GRAPHICS CLEAR .9,1,1
IF NOT FILE_EXISTS(Ext.Dir$) THEN DIR Ext.Dir$ CREATE
IF NOT FILE_EXISTS(Ext.Dir$&Ext.CurrData$) THEN
  DRAW FONT SIZE 25*rw
  DRAW COLOR 0,0,0
  DRAW TEXT "Loading data..." at sw/2,sh/3
  SPRITE "progress" LOAD "loader.GIF"
  SPRITE "progress" AT sw/2,sh*.6 SCALE 1
  SPRITE "progress" DELAY .05 
  SPRITE "progress" SHOW
  SPRITE "progress" PLAY 
  GOSUB UpdateData
  GOSUB LoadCategories
  SPRITE "progress" HIDE
ENDIF
GRAPHICS CLEAR .9,1,1
OPTION SPRITE POS NORMAL
OPTION TEXT POS NORMAL

'  load currency and inflation data
CALL Ext(Ext.curr$)
CALL Ext(Ext.inflEuroCat$)
CALL Ext(Ext.inflUSDCat$))
''
'r'   load preferences
CALL Pref(0)
/*
User choice of interface when updating currency exchange rates:
Silent: view=0
Interactive: view=1
Currency named by YearDate: cpref=0
Currency named by DateTime: cpref=1
*/
 view=VAL(Pref.view$)
 cpref=VAL(Pref.cpref$)
''
' interface object names

x$="guide"
y$="guide2"
n$="title"
o$="category"
p$="from"
q$="to"
pi$="from_in"
qi$="to_in"
qi2$="cover"
q$=CHR$(34)
cat=1          ' default category (angle)
invalue=1
upshift=7

' correction for iPad display only
IF rw=1 then shift=10

' correction for non-iPad display only
IF rw<1 THEN shift2=75 ELSE shift2=-6

fm$="##,###,###,###,###,###,###.#######"    ' formats the result with commas
fm2$="####################.#######"      ' formats the result without commas

'b'============ Initialisation============
''
 ' animate title if gif animation file exists

PAGE "title" FRAME 0,0,sw,80
PAGE "title" SET
PAGE "title" SHOW
A$="iconvert3.GIF"
IF FILE_EXISTS(A$) THEN
  SPRITE N$ LOAD A$
  SPRITE N$ AT sw/3-shift2,sh/60+3*shift scale 1*rh
  SPRITE N$ SHOW
ELSE
  DRAW IMAGE "iconvert.PNG" AT sw/2.8,sh/20 SCALE .8*rw
ENDIF
PAGE "" SET


' read categories
GOSUB LoadCategories

RESTORE TO acceleration     ' default category
GOSUB setcategory


' create three lists

SET LISTS FONT SIZE 18*rw
LIST o$ TEXT cat$ AT sw*.1,260*rh SIZE 260*rw,310*rh
LIST o$ SELECT cat
LIST p$ TEXT measure$ AT sw*.395,260*rh SIZE 240*rw,310*rh
LIST p$ SELECT 1
LIST q$ TEXT measure$ AT sw*.672,260*rh SIZE 240*rw,310*rh
LIST q$ SELECT 1


' create fields and buttons

GOSUB FieldsAndButtons

timer=time ()    ' set timer to stop title anim after one cycle

'b'========== main program loop ===================
''
DO
' play once, then stop animation

IF time()-timer>1 AND time()-timer <2 and not noplay THEN
  IF FILE_EXISTS(A$) THEN SPRITE N$ PLAY
  noplay=1
ENDIF
IF time()-timer>6 AND time()-timer <7 THEN
  IF FILE_EXISTS(A$) THEN SPRITE N$ STOP
ENDIF

' check which category is selected

type=LIST_SELECTED(o$)


' choose and prepare a new category if necessary

IF type<>cat THEN GOSUB CatChange

IF LIST_SELECTED(p$)<>selp or LIST_SELECTED(q$)<>selq then changed=1


' calculate the conversion

if VAL(FIELD_TEXT$(pi$))<>invalue or changed then
  invalue=VAL(FIELD_TEXT$(pi$))
  selp=LIST_SELECTED(p$)
  selq=LIST_SELECTED(q$)
  GOSUB Convert ' calculate OutValue
  if outvalue<100000000 and outvalue>.000000001 then 
    out$=STR$(outvalue,fm$)
    out2$=STR$(outvalue,fm2$)
    format(out$)!out$=format.form$
    format(out2$)!out2$=format.form$
  else
    out$=STR$(outvalue)
  endif
  fsize=22*rw
  FIELD qi$ FONT SIZE fsize
  FIELD qi$ TEXT out$
  FIELD qi2$ TEXT ""
ENDIF

IF bp("settings") THEN
  showswitch=1
  gosub settings
ENDIF

IF bp("help") THEN
  FIELD qi$ HIDE
  gosub help
ENDIF
'
IF bp("update") THEN
  gosub updatedata
  GOSUB LoadCategories
  LIST o$ TEXT cat$
  LIST p$ TEXT measure$
  LIST q$ TEXT measure$
  LIST o$ SELECT cat
  LIST p$ SELECT 1
  LIST q$ SELECT 1
  LIST o$ SHOW
  LIST p$ SHOW
  LIST q$ SHOW
ENDIF


' copy the conversion info to clipboard

IF bp("copy") THEN
  GOSUB compile
  IF cp=0 THEN!CLIPBOARD CLEAR!cp=1!ENDIF
  CLIPBOARD WRITE convert$
  BEEP
ENDIF


' print the conversion info

IF bp("print") THEN
GOSUB compile
h$(1) = "content-type:text/html"   ' make header info
h$(2) = "content-length:" & LEN(convert$)

' print convert$ using Henko print technique
HTTP URL$ HEADER H$ POST convert$   ' send doc to the print server
BEEP
ENDIF


' save the conversion info to a file

IF bp("save") THEN
  GOSUB compile
  fname$="converted.txt"
  IF FILE_EXISTS(fname$) THEN FILE fname$ DELETE
  FILE fname$ WRITELINE convert$
  BEEP
ENDIF


' end the program

IF bp("stop") THEN
  Pref.view$=STR$(SWITCH_STATE ("inter"))
  Pref.cpref$=STR$(SWITCH_STATE ("cpref"))
  CALL Pref(1)
  IF laun$="desktop" THEN
    IF FILE_EXISTS("/launch") THEN
      RUN "/-Launch.sb"
    ELSE
      EXIT
    ENDIF
  ENDIF
  END
ENDIF

' close help screen

if bp("closer") THEN
  BUTTON "closer" HIDE
  BROWSER "n" HIDE
  FIELD qi$ SHOW
ENDIF
SLOWDOWN
UNTIL 0
END


'g'========== Subroutines and Functions =============

Convert:
'--- Convert via formula
'  temperature
IF Cat$(cat)=Tscale$ THEN
  Outvalue=FromCelsius(Celsius(Invalue,measureval(selp)),measureval(selq))
  RETURN
ENDIF
'--- Calculate inflation
IF Cat$(cat)=Ext.EuroCat$ THEN
  Outvalue=Inflation(Invalue,selp,selq)
  Pref.EuroSel$=PreSel$(selp,selq)
  RETURN
ENDIF
IF Cat$(cat)=Ext.USDCat$ THEN
  Outvalue=Inflation(Invalue,selp,selq)
  Pref.USDSel$=PreSel$(selp,selq)
  RETURN
ENDIF
IF Cat$(cat)=Ext.currcat$ THEN Pref.currsel$=PreSel$(selp,selq) 
'--- Convert via ratio
  outvalue=invalue*measureval(selp)/measureval(selq)
RETURN
''
'g'
DEF PreSel$(p1,p2)
' make Preselect string
s$=STR$(p1,"#")&","&STR$(p2,"#")
RETURN s$
END DEF
''
'g'
DEF Preselect(cat)
' preselect if available
p1=1 ! p2=1
IF .Cat$(cat)=Ext.CurrCat$ THEN
  Sel$=Pref.Currsel$ ! GOTO Select
ENDIF
IF .Cat$(cat)=Ext.EuroCat$ THEN
  Sel$=Pref.Eurosel$ ! GOTO Select
ENDIF
IF .Cat$(cat)=Ext.USDCat$ THEN
  Sel$=Pref.USDsel$ ! GOTO Select
ENDIF
RETURN ' no result
Select:
  SPLIT Sel$&" " TO p$,n with ","
  IF n<2 THEN RETURN
  P1=VAL(p$(1)) ! p2=VAL(p$(2))
RETURN
END DEF
''
'g'
DEF Pref(save)
' store preferences if save=1 else read
' by Dutchman
OldFile$="viewstat" ' prefix
'--- Define the items
Prefvars:
prefs=5 ' number of items
DATA View$,Cpref$,CurrSel$,EuroSel$,USDsel$
Default:
DATA "0","0","1,1","1,1","1,1" ' Last data line!
'
'--- Initiate
IF File$="" THEN GOSUB Initiate
'--- Save preferences
IF Save THEN
  ' be sure that extra lines are removed
  IF FILE_EXISTS(File$) THEN FILE File$ DELETE
  ' write new
  FILE File$ WRITELINE View$&"  interactive mode"
  FILE File$ WRITELINE Cpref$&"  currency datetime mode"
  FILE File$ WRITELINE Currsel$&"  Currency select"
  FILE File$ WRITELINE Eurosel$&"  Inflation Euro select"
  FILE File$ WRITELINE USDsel$&"  Inflation US dollar select"
ENDIF
RETURN ' from function
'--- Local subroutines
SetDefault: '--------------------
ON i GOTO a,b,c,d,e
a: View$=a$(1) ! RETURN ' from sub
b: Cpref$=a$(2) ! RETURN ' from sub
c: CurrSel$=a$(3) ! RETURN ' from sub
d: EuroSel$=a$(4) ! RETURN ' from sub
e: USDsel$=a$(5) ! RETURN ' from sub
RETURN ' ftom SetDefault
Initiate: '----------------------
'   determine items
RESTORE TO Prefvars
DIM Data$(Prefs)
WHILE DATA_EXIST()  and items<=Prefs*2
  items+=1 ! READ a$(items)
END WHILE
IF prefs<>items/2 THEN
  TEXT ! TEXT CLEAR
  PRINT "Incorrect number of items in function ""Pref()""."
STOP ! ENDIF
'--- read or create file
File$=Ext.Preferences$
'--- rename oldfile
ExFile$=LatestFile$(".",OldFile$,1)
IF ExFile$<>"" THEN 
  IF FILE_EXISTS(File$) THEN 
    FILE ExFile$ DELETE
  ELSE ! FILE ExFile$ RENAME File$
  ENDIF
ENDIF
'   remove rest
ExFile$=LatestFile$(".",OldFile$,1)
IF ExFile$<>"" THEN FILE ExFile$ DELETE
'--- preset defaults
RESTORE TO Default
DIM a$(prefs)
FOR i=1 TO Prefs
  READ a$(i)
  GOSUB SetDefault
NEXT i
'--- load data
IF FILE_EXISTS(File$) THEN
  FILE File$ SETPOS 0
  items=0
  WHILE items<=Prefs AND (NOT FILE_END(File$))
    items+=1
    ON items GOTO view,cpref, CurrSel,EuroSel,USDsel
view: FILE File$ READLINE View$
   View$=Pref$(view$,",") ! IF view$="" THEN View$=a$(1)
   GOTO Done
cpref: FILE File$ READLINE Cpref$
    Cpref$=Pref$(Cpref$,",") !  ! IF cpref$="" THEN cpref$=a$(2)
    GOTO Done
CurrSel: FILE File$ READLINE CurrSel$
    CurrSel$=Pref$(CurrSel$,",") ! IF currsel$="" THEN currsel$=a$(3)
    GOTO Done
EuroSel: FILE File$ READLINE EuroSel$
    EuroSel$=Pref$(EuroSel$,",") ! IF Eurosel$="" THEN Eurosel$=a$(4)
    GOTO Done
USDsel: FILE File$ READLINE USDsel$
    USDsel$=Pref$(USDsel$,",") ! IF USDsel$="" THEN USDsel$=a$(5)
    GOTO Done
  Done:
  END WHILE
ENDIF
Save=1
RETURN ' from initiate
END DEF
''
'g'
DEF Pref$(t$,sep$)
' extract numbers and sep$
nr$="0123456789" ! n=LEN(t$)
IF n<1 THEN RETURN ""
out$="" ! i=0
DO
  i+=1
  p$=MID$(t$,i,1)
  IF INSTR(nr$&sep$,p$,1)>0 THEN Out$&=p$
UNTIL p$=" " ' was: i=n
RETURN Out$
END DEF
''
'g' temperature conversion

DEF FromCelsius(Value,UnitPointer)
'Converts Value on 'Unit'-scale to Celsius-scale
'  to newvalue in scale of Unitpointer
ON UnitPointer GOTO 1,2,3,4,5,6,7,8
  1 RETURN Value 'Celsius
  2 RETURN Value+273.15 'Kelvin
  3 RETURN Value*9/5+32 'Fahrenheit
  4 RETURN (Value+273.15)*9/5 'Rankine
  5 RETURN (100-Value)*3/2 'Delisle
  6 RETURN Value*33/100 'Newton
  7 RETURN Value*4/5 'Réamur
  8 RETURN Value*21/40+7.5 'Rømer
END DEF
'
DEF Celsius(Value,UnitPointer)
'Converts Value in 'Unit' to new value in Celsius
ON UnitPointer GOTO 1,2,3,4,5,6,7,8
  1 RETURN Value 'Celsius
  2 RETURN Value-273.15 'Kelvin
  3 RETURN (Value-32)*5/9 'Fahrenheit
  4 RETURN (Value-491.67)*5/9 'Rankine
  5 RETURN 100-Value*2/3 'Delisle
  6 RETURN Value*100/33 'Newton
  7 RETURN Value*5/4 'Réamur
  8 RETURN (Value-7.5)*40/21 'Rømer
END DEF
''
'g' choose and prepare a new category

CatChange:
oldcat=cat
cat=type
changed=1
ON cat GOTO accel,angles,areas,cook,curr,datasize,energ,entrans,flow,freq,ill,inflEuro,inflUSD,leng,lum,prefix,pow,press,spd,tscales,time,vol,wgt
accel:
  RESTORE TO acceleration ! GOTO skip
angles:
  RESTORE TO angle ! GOTO skip
areas:
  RESTORE TO area ! GOTO skip
cook:
  RESTORE TO cooking ! GOTO skip
curr:
   CALL Ext(Cat$(cat))
   GOTO skipped
datasize:
  RESTORE TO data ! GOTO skip
energ:
  RESTORE TO energy ! GOTO skip
entrans:
  RESTORE TO EnergyTransition ! GOTO skip
flow:
  RESTORE TO FlowRate ! GOTO skip
freq:
  RESTORE TO Frequency ! GOTO skip
ill:
  RESTORE TO illuminance ! GOTO skip
inflEuro:
  CALL Ext(Cat$(cat))
  GOTO Skipped
inflUSD:
  CALL Ext(Ext.inflUSDCat$))
  GOTO Skipped
leng:
  RESTORE TO length ! GOTO skip
lum:
  RESTORE TO luminance ! GOTO skip
prefix:
  RESTORE TO prefixes ! GOTO skip
pow:
  RESTORE TO power ! GOTO skip
press:
  RESTORE TO pressure ! GOTO skip
spd:
  RESTORE TO speed ! GOTO skip
tscales:
  RESTORE TO Temperatures ! GOTO Skip
time:
  RESTORE TO timing ! GOTO skip
vol:
  RESTORE TO volume ! GOTO skip
wgt:
  RESTORE TO weight ! GOTO skip
'--- 
skip: 
  GOSUB setcategory
skipped:
  LIST p$ TEXT measure$
  LIST q$ TEXT measure$
  FIELD pi$ TEXT "1"
  CALL Preselect(cat)
  LIST p$ SELECT Preselect.p1
  LIST q$ SELECT Preselect.p2
RETURN

' read the data for a category

setcategory:
READ items
DIM measure$(items)
DIM measureval(items)
FOR t=1 TO items
  READ measure$(t)
 READ measureval(t)
NEXT t
RETURN

'  load or rewrite categories

LoadCategories:
'  read data
RESTORE TO Categories
READ cats
DIM Cat$(cats)
FOR t=1 TO cats
  READ cat$(t)
NEXT t
RETURN

' prepare a string showing the conversion, for copying or saving to a file

compile:
  selp=LIST_SELECTED(p$)
  selq=LIST_SELECTED(q$)
  temp1$=measure$(selp)
  temp2$=measure$(selq)


  ' if a value is 1 or a fraction, change the name from plural to singular
  convin=val(FIELD_TEXT$(p$))
  temp1len=LEN(temp1$)
  IF convin=<1 AND RIGHT$(temp1$,1)="s" THEN temp1$=LEFT$(temp1$,temp1len-1)
  IF VAL(out2$)=<1 AND RIGHT$(temp2$,1)="s" THEN temp2$=LEFT$(temp2$,LEN(temp2$)-1)
  convert$&=FIELD_TEXT$(pi$)&" "&temp1$&" = "&FIELD_TEXT$(qi$)&" "&temp2$
  convert$&=cr$&lf$&FIELD_TEXT$(pi$)&" "&temp1$&" = "&out2$&" "&temp2$&cr$&lf$&cr$&lf$
RETURN


' settings window

settings:
a$=lf$&"When updating currency data, choose if you want interactive mode. When the switch is off, the currency exchange file is updated without interactivity. When the switch is on, the file is updated interactively with the user."&lf$&lf$&lf$&lf$&"For currency year & date, leave off. For currency date & time switch ON."
pw("notice","Settings",a$,sw/2-200*rw,sh/4,400*rw,400*rw,1,1,1,1)
goto message
'r'
message:
wait: SLOWDOWN
IF SWITCH_CHANGED("inter") THEN
  .view=SWITCH_STATE("inter")
  Pref.view$=STR$(.view)
ENDIF
IF SWITCH_CHANGED("cpref") THEN
  .cpref=SWITCH_STATE("cpref")
  Pref.cpref$=STR$(.cpref)
ENDIF
CALL Pref(1)
IF BUTTON_PRESSED("close") THEN
  PAGE pw.NAME$ HIDE ! PAGE "" SET ! PAGE "" SHOW
  GOSUB drawscreen
ELSE 
  GOTO wait
ENDIF
RETURN
''
'g'
drawscreen:
  FILL COLOR .6,.8,.8
  FILL RECT sw*.395,145*rh TO sw*.6,185*rh-vshift
  FILL COLOR .8,.8,.8
  FILL RECT sw*.635,140*rh TO sw*.92,190*rh-vshift
  DRAW COLOR 0,0,0
  DRAW RECT sw*.1-1,258*rh TO sw*.1+260*rw+1,258*rh+312*rh
  DRAW RECT sw*.3955-2,258*rh TO sw*.3955+240*rw,258*rh+312*rh
  DRAW RECT sw*.673-2,258*rh TO sw*.673+240*rw,258*rh+312*rh
  DRAW LINE sw*.26,168*rh TO sw*.392,168*rh
  DRAW LINE sw*.096,618*rh TO sw*.38,618*rh
  DRAW LINE sw*.63,618*rh TO sw*.91,618*rh
  FILL COLOR 0,0,0
  FILL CIRCLE sw*.39,168*rh SIZE 3*rw
  FILL COLOR .8,.8,.8
  SET BUTTONS FONT NAME "Arial"
RETURN

' create fields and buttons

FieldsAndButtons:
SET BUTTONS FONT SIZE 20*rw
SET BUTTONS FONT NAME "Arial"
DRAW COLOR 0,0,0
guide$="Pick from each list"&lf$&"Enter quantity here"
FILL COLOR 0,0,0
FILL CIRCLE sw*.39,168*rh SIZE 3*rw
FILL COLOR 1,1,1
FIELD x$ TEXT guide$ AT sw*.1,132*rh-upshift SIZE 250,60 RO ML
FIELD x$ FONT SIZE 18*rw
FIELD x$ BACK ALPHA 0
guide2$="All lists can be scrolled"
DRAW LINE sw*.26,168*rh TO sw*.392,168*rh
DRAW LINE sw*.096,618*rh TO sw*.38,618*rh
DRAW LINE sw*.63,618*rh TO sw*.91,618*rh
FIELD y$ TEXT guide2$ AT sw*.41,600*rh-upshift*.8 SIZE 250,60 RO ML
FIELD y$ FONT SIZE 18*rw
FIELD y$ BACK ALPHA 0
FIELD o$ TEXT "CATEGORY" AT sw*.115,210*rh SIZE 130,30 RO
FIELD o$ FONT SIZE 20*rw
FIELD o$ BACK ALPHA 0
FIELD p$ TEXT "FROM" AT sw*.405,210*rh SIZE 100,30 RO
FIELD p$ FONT SIZE 20*rw
FIELD p$ BACK ALPHA 0
FIELD q$ TEXT "TO" AT sw*.69,210*rh SIZE 70,30 RO
FIELD q$ FONT SIZE 20*rw
FIELD q$ BACK ALPHA 0
FILL ALPHA 0
SET BUTTONS FONT SIZE 24*rw
BUTTON "settings" TEXT CHR$(9881) AT 90*rw,648*rh SIZE 50*rw,50*rh
SET BUTTONS FONT SIZE 20*rw
BUTTON "help" TEXT "HELP" AT 170*rw,650*rh SIZE 100*rw,50*rh
BUTTON "update" TEXT "UPDATE" AT 300*rw,650*rh SIZE 100*rw,50*rh
BUTTON "copy" TEXT "COPY"  AT 420*rw,650*rh SIZE 100*rw,50*rh
BUTTON "print" TEXT "PRINT" AT 540*rw,650*rh SIZE 100*rw,50*rh
BUTTON "save" TEXT "SAVE" AT 660*rw,650*rh SIZE 100*rw,50*rh
BUTTON "stop" TEXT "STOP" AT 780*rw,650*rh SIZE 100*rw,50*rh
FILL ALPHA 1
FIELD pi$ TEXT "1" AT sw*.400,150*rh SIZE 200*rw,30*rh
FIELD pi$ FONT SIZE 18*rw
FIELD qi$ TEXT "1" AT sw*.640,145*rh SIZE 280*rw,40*rh
FIELD qi$ FONT SIZE 22*rw
FIELD qi2$ TEXT "" AT sw*.640,145*rh SIZE 280*rw,40*rh RO
FIELD qi2$ BACK ALPHA 0
if rw<1 then vshift=2
FILL COLOR .6,.8,.8
FILL RECT sw*.395,145*rh TO sw*.6,185*rh-vshift
FILL COLOR .8,.8,.8
FILL RECT sw*.635,140*rh TO sw*.92,190*rh-vshift
DRAW RECT sw*.1-1,258*rh TO sw*.1+260*rw+1,258*rh+312*rh
DRAW RECT sw*.3955-2,258*rh TO sw*.3955+240*rw,258*rh+312*rh
DRAW RECT sw*.673-2,258*rh TO sw*.673+240*rw,258*rh+312*rh
RETURN
''

'm'

'prepare help browser text string in html code 

helpset:
IF rw<1 THEN
' create the help page to display in browser
brow$="<!DOCTYPE html><HEAD><style>h5 {TEXT-align:center;}  body {border: solid;padding:0;margin:1;} div#opt1 {text-align: center;} span#msg {color:red;} .selected {border: solid 1px; background-color: #d0d0d0; color:blue;}</style>"&js$&"</HEAD><body><html><h5>iConvert User Guide</h5><h6>"
ELSE
brow$="<!DOCTYPE html><HEAD><style>h2 {TEXT-align:center;} input {width:64;height:32;} body {border: solid;padding:1;margin:10;} div#opt1 {text-align: center;} span#msg {color:red;} .selected {border: solid 1px; background-color: #d0d0d0; color:blue;}</style>"&js$&"</HEAD><body><html><h2>iConvert User Guide</h2><h3>"
ENDIF
brow$&="<ol><li> First choose one of the 18 categories, such as Area.</li><li>Next, choose the measure to convert From. You can leave the From field as 1, or enter the number of units to convert.</li><li>Finally pick the measure to convert To, and you will see the result in the To field.</li></ol>&nbsp;&nbsp;BUTTONS: (from left to right)<ol><li>The Settings button is described under SETTINGS.</li><li>The Help button brings you to this page.🙂</li><li>The Update button fetches new currency exchange data.</li><li>The Copy button copies your conversions to the clipboard.</li><li>The Print button sends your conversions to a PC print server if one is running.</li><li>The Save button saves your conversions to a file named convert.txt.</li><li>The Stop button ends the program.</li></ol><ul><li>Most of the categories contain measures that rarely change with respect to each other. But some of the newer categories have measures that can change rapidly.</li><li>The Currency category is one of them. It compares some 54 world currencies which can change hourly.<br>It requires regular downloads from a currency website.</li><li>When you run iConvert for the first time, the Loading message indicates that some of these files are being written.</li><li>Two of them, 'currencies.html [date]' and 'currencies.table' are used to provide the data needed to compare currencies.</li> <li>A third file, 'viewdata1', stores the choices that you make in Settings.</li><li>SETTINGS: When you press the ⚙️ button, a popup window appears. In it are two switches, with explanations of what they do. With the top switch off (default), currency data is updated invisibly. With the top switch on, you view a web page of currency data during updates, and are given some choices at the top of the screen. With the bottom switch off (default), the Currency category is labelled with the year, month and date of creation. With the bottom switch on, it is labelled with the month, date, hour and minute of creation.</li></ul></html>"
IF rw<1 THEN
brow$&="</h6>"
ELSE
brow$&="</h3><br>"
ENDIF
return


'create help browser popup

help:
  popup(0,5*rh,1024*rw,725*rh,brow$,1)
  DRAW COLOR 0,0,0
  SET BUTTONS FONT SIZE 20*rw
  FILL COLOR 1,1,1
  BUTTON "closer" TEXT "X" AT 30*rw,30*rh
  BUTTON "closer" SHOW
return

' Function to create a browser popup for Help

DEF POPUP(X,Y,W,H,T$,SHOW)  
BROWSER "n" AT X,Y SIZE W,H
BROWSER "n" TEXT T$
IF SHOW THEN
BROWSER "n" SHOW
ELSE
BROWSER "n" HIDE
ENDIF
END DEF
''
'y'
UpdateData:
' Update Currencies by Dutchman, October 2018
'==== Presets ====
GOSUB PresetView
'
'==== Main Update Routine ====
IF Update(View,Top$) THEN
 FIELD Top$ BACK COLOR 0,0,1
  Field Top$ TEXT  "Data written to """&SortAndStore.File$&"""."
ELSE
  FIELD Top$ BACK COLOR 1,0,0
  Field Top$ TEXT Update.Msg$
ENDIF
PAUSE 2
FIELD Top$ BACK COLOR 0,0,1
FIELD Top$ HIDE
BROWSER "a" HIDE
Ext.CurrLoaded=0 ' read new currency data
CALL Ext(Ext.Curr$)
GOSUB LoadCategories
GOSUB drawscreen
RETURN
'
'c'========== External data Subroutines and Functions ===========
DEF Ext(cat$) ' load and store external data
'   Data folder
Dir$="Data/"
'----- Category and datafile names
Preferences$=Dir$&"preferences"
'  Currency
Curr$="Currency " ! CurrData$="currencies.table"
IF NOT CurrLoaded THEN CurrCat$=Curr$& "❌ Error"
'  Inflation Euro
InflEuro$= "inflation Euro" ! EuroData$=InflEuro$&".table"
inflEuroCat$="Inflation Euro "
IF NOT EuroLoaded THEN EuroCat$=inflEuroCat$
'  Inflation US dollar
InflUSD$="inflation US dollar" ! USDData$=InflUSD$&".table"
inflUSDCat$="Inflation US dollar "
IF NOT USDLoaded THEN USDCat$=inflUSDCat$
'
'---  currencies ---
IF INSTR(Cat$,Curr$,1)>0 THEN
  Table$=CurrData$
  CALL Table(Table$) ' for update if necessary
  IF currloaded THEN TransferCurr
  CALL Table(Table$)
  curr=Table.count ! CurrDate$=Table.date$
  CurrCat$=Curr$&CurrDate$
  DiM CurrName$(Table.count), CurrValue(Table.count)
  FOR i=1 TO Table.Count
    CurrName$(i)=Table.Name$(i)
    CurrValue(i)=Table.Value(i)
  NEXT i
  CurrLoaded=1
TransferCurr:
  DIM .measure$(curr), .measureval(curr)
  FOR i=1 TO Curr
    .measure$(i)=CurrName$(i)
    .measureval(i)=CurrValue(i)
  NEXT i
ENDIF ' currencies end
'
'--- inflationEuro ---
IF INSTR(Cat$,inflEuroCat$,1)>0 THEN
  Table$= EuroData$
  IF Euroloaded THEN TransferEuro
  CALL Table(Table$)
  Euros=Table.count ! EuroDate$=Table.date$
  IF INSTR(EuroDate$,"❌",1)<1 THEN EuroDate$=LEFT$(EuroDate$,4)
  EuroCat$= inflEuroCat$&EuroDate$
  DiM EuroName$(Table.count), EuroValue(Table.count)
  FOR i=1 TO Table.Count
    EuroName$(i)=Table.Name$(i)
    EuroValue(i)=Table.Value(i)
  NEXT i
 EuroLoaded=1
TransferEuro:
  DIM .measure$(Euros), .measureval(Euros)
  FOR i=1 TO Euros
    .measure$(i)= EuroName$(i)
    .measureval(i)= EuroValue(i)
  NEXT i
ENDIF ' Euros end
'
'--- inflation US dollar ---
IF INSTR(Cat$,inflUSDCat$,1)>0 THEN
  Table$=USDData$
  IF USDloaded THEN TransferUSD
  CALL Table(Table$)
  USDs=Table.count ! USDDate$=Table.date$
  IF INSTR(USDDate$,"❌",1)<1 THEN USDDate$=LEFT$(USDDate$,4)
  USDCat$= inflUSDCat$& USDDate$
  DiM USDName$(Table.count), USDValue(Table.count)
  FOR i=1 TO Table.Count
    USDName$(i)=Table.Name$(i)
    USDValue(i)=Table.Value(i)
  NEXT i
 USDLoaded=1
TransferUSD:
  DIM .measure$(USDs), .measureval(USDs)
  FOR i=1 TO USDs
    .measure$(i)= USDName$(i)
    .measureval(i)= USDValue(i)
  NEXT i
ENDIF ' USDs end
' not external data
RETURN
END DEF
''
'c'
DEF Table(file$)
File$=Ext.Dir$&File$
IF NOT FILE_EXISTS(File$) THEN
  GOSUB Error ! count=1
  RETURN count
ENDIF
' read data from table
FILE File$ SETPOS 0
FILE File$ READLINE Title$
FILE File$ READLINE Date$
Date$=TRIM$(LEFT$(Date$,9))
FILE File$ READLINE Count
IF Count<1 THEN Count=1
DIM Name$(count), Value(count), Rest$(count)
IF Count=1 THEN
  GOSUB Error
ELSE
  FOR n=1 TO count
    FILE File$ READLINE Line$
    SPLIT Line$ TO a$,a WITH ";"
    Name$(n)=a$(1) ! Value(n)=VAL(a$(2))
    IF a>2 THEN ' save Rest$
      FOR i=3 TO a
         Rest$(n)&=a$(i)&";"
      NEXT i
    ENDIF
  NEXT n
ENDIF
RETURN count
Error: ' local sub
Name$(1)="Not loaded"
Value(1)=1
Date$="❌ Error"
RETURN 'from local sub
END DEF
''
'c'
DEF Inflation(Invalue,index1,index2)
N1$=.measure$(index1) !N2$=.measure$(index2)
Val1=.measureval(index1) ! Val2=.measureval(index2)
first=MIN(index1,Index2) ! last=MAX(Index1,Index2)
Total=1
FOR n=first TO last-1
  Total*=1+.measureval(n)/100
NEXT n
IF Index1>Index2 THEN RETURN Invalue/Total
RETURN Invalue*Total
END DEF
'r'========== Update Subroutines and Functions ===========
PresetView:
IF NOT viewpreset THEN
  '--- presets
  Top=MAX(17,MIN(sw,sh)/32) ' top space
  YesNoPos=sw/2 ' x-position of buttons
  TopFont=0.7*top 'fontsize
  '--- Prepare browser
  SET BROWSERS SCALED
  BROWSER "a" AT 0,top SIZE sw,sh-top
  BROWSER "a" HIDE
  '--- make buttons
  SET BUTTONS FONT SIZE topfont
  SET BUTTONS FONT NAME "Menlo"
  DRAW COLOR 1,1,0
  FILL COLOR 1,0,0
  BUTTON "yes" TEXT "Yes" AT YesNoPos,0 SIZE 3*top,top
  BUTTON "yes" HIDE
  BUTTON "no" TEXT "No" AT YesNoPos+3*top,0 SIZE 3*top,top
  BUTTON "no" HIDE
  '--- Make Messagefield
  Top$="In" ' Field for input
  FIELD Top$ AT 0,0 SIZE sw/2,top
  FIELD Top$ FONT NAME "Menlo"
  FIELD Top$ FONT SIZE topfont
  FIELD Top$ FONT COLOR 1,1,0
  FIELD Top$ BACK COLOR 0,0,1
  FIELD Top$ HIDE
  '--- don't recall
  viewpreset=1
ENDIF
RETURN
''
'r'
DEF Update(view,iField$)
'--- constants
Source$="https://www.x-rates.com/table/?from=USD&amount=1"
SourceCom$="x-rates.com"
MaxCount=100 ' max number of currencies
WebPage$="currencies.html" ' undated webpage filename
'--- Output variables
OK=0
DIM Data$(maxcount,2) ' array for extracted data
DataFile$=Ext.CurrData$ ' file with DATA-lines
'--- messagebar
IF view THEN
  FIELD iField$ SHOW
  FIELD iField$ BACK COLOR 0,0,1
ENDIF
'--- Check net response
Msg$=NetStatus$(SourceCom$)
IF NetStatus$.level<>2 THEN RETURN 0
'--- purge html-files
CALL LatestFile$(Ext.Dir$,webpage$,1)
'--- Select and store source
IF view THEN web$=LatestFile$(Ext.Dir$,webpage$,0)
IF web$="" THEN web$=WebPage$
web$=MakeCurrencyHTML$(Source$,Ext.Dir$&Web$,view,iField$,"a")
IF web$="fail" THEN web$=LatestFile$(Ext.Dir$,webpage$,0)
IF web$="" THEN 
  Msg$="Cancelled."
  RETURN 0
ENDIF
'---- Extract data from HTML-file
IF View THEN FIELD iField$ SHOW
FIELD iField$ BACK COLOR 0,0,1
FIELD iField$ TEXT "Extracting second table."
IF ExtractHtml(view,web$,Data$,iField$)=0 THEN
  Msg$=ExtractHtml.Msg$
  RETURN 0
ENDIF
'--- Sort and write to data-file
FIELD iField$ TEXT "Writing to """&DataFile$&"""."
CALL SortAndStore(Ext.Dir$&DataFile$,Data$,ExtractHtml.count)
OK=1
RETURN 1
END DEF
''
'r'
DEF SortAndStore(File$,Data$(,),items)
Quicksort$(Data$,items,2,1)
Date$= ExtractHtml.DataDate$
items+=1 'add 1 to include reference value US-dollar
'--- Make table-file
IF FILE_EXISTS(File$) THEN FILE File$ DELETE
FILE File$ PRINT "Currency"
FILE File$ PRINT Date$&" = download date"
FILE File$ PRINT items&" = items in Currencies"
File File$ PRINT "US dollar"&"; 1"
FOR i=1 TO items-1
  File File$ PRINT Data$(i,1)&"; "&Data$(i,2)
NEXT i
END DEF
''
'r'
DEF ExtractHtml(view,HtmlFile$,Data$(,),iField$)
/* single item in HTML-text to parse:
<tr>
<td>Argentine Peso</td>
<td class='rtRates'><a href='… url …/?from=USD&amp;to=ARS'>36.446414</a></td> 
<td class='rtRates'><a href='… url …/?from=ARS&amp;to=USD'>0.027438</a></td> 
</tr>
*/
count=0
'--- Read body into a$
GOSUB ReadTableBody ' local subroutine
IF Msg$<>"" THEN RETURN 0
'--- Store HTML table-rows
p1=INSTR(a$,"<tr",1)
WHILE p1>0 AND count<update.maxcount
 p2=INSTR(a$,"/tr>",p1)
  first=p2 
  IF first>0 THEN
    count+=1
    Data$(count,1)=SUBSTR$(a$,p1,p2)
  ENDIF
  p1=INSTR(a$,"<tr",first)
END WHILE
'--- Check table-size
IF count>=update.maxcount THEN
  Msg$="Data-array is too small. Increase constant 'Update.Maxcount'."
  RETURN 0
ENDIF
'--- extract valuta and value
FOR i=1 TO count
  p1=INSTR(Data$(i,1),"<td>",1)+4
  p2=INSTR(Data$(i,1),"<",p1)-1
  Valuta$=SUBSTR$(Data$(i,1),p1,p2)
  p1=INSTR(Data$(i,1),"to=USD'>",p2)+8
  p2=INSTR(Data$(i,1),"</a",p1)-1
  Value$= SUBSTR$(Data$(i,1),p1,p2)
  Data$(i,1)=Valuta$ ! Data$(i,2)=Value$
NEXT i
RETURN 1  ' all OK 
ReadTableBody: ' ------------ local subroutine
'--- Extract date from filename
DataDate$=TRIM$(RIGHT$(TRIM$(HtmlFile$),9))
'--- Find second table
FILE HtmlFile$ SETPOS 0
Msg$="Second marker """&"tbody"&""" not found."
FOR i=1 TO 2
  DO
    FILE HtmlFile$ READLINE Line$
    IF Line$<>"" THEN p1=INSTR(Line$,"<tbody",1)
  UNTIL p1>0 OR FILE_END(HtmlFile$)
  IF FILE_END(HtmlFile$) THEN RETURN 'Msg$ is set
NEXT i
IF p1<1  THEN RETURN' Msg$ is preset
'--- Read table-body
a$=Line$
DO
  FILE HtmlFile$ READLINE Line$
  a$&=Line$
  p2=INSTR(a$,"/tbody",1)
UNTIL FILE_END(HtmlFile$) OR p2>0
Msg$&=" (no end-marker)"
IF p2<1 THEN RETURN ' Msg$ is preset
Msg$=""
RETURN ' from local sub
END DEF
''
'r'
DEF MakeCurrencyHTML$(Url$,HtmlFile$,iview,iField$,Browser$)
'HtmlFile$ contains name of existing file or undated name
'returns filename if HtmlFile$ is updated
'If 'htm-file$' was not existing then name is extended with date
IF FILE_EXISTS(HtmlFile$) AND iView THEN
  prompt$ ="Latest update: "
  prompt$&= RIGHT$(HtmlFile$,8)
  prompt$&=". Download new?"
  Answer$=Input$(iField$, prompt$)
  FIELD iField$ BACK COLOR 0,0,1
  IF Answer$="n" THEN
    NewData=0
    FIELD iField$ BACK COLOR 0,0,1
    Field iField$ TEXT  "Reading data"
    BROWSER Browser$ SHOW
    GOSUB HideFields ' local subroutine
    BROWSER Browser$ TEXT PageContent$(HtmlFile$)
  ELSE ! NewData =1
  ENDIF
ELSE ! NewData =1
ENDIF
'----  Update webdata
IF NewData THEN
  SPLITE HtmlFile$ TO a$,n with "."
  HtmlFile$=a$(1)&".html "&ISO_Date$
  FIELD iField$ BACK COLOR 0,0,1
  Field iField$ TEXT  "Collecting data"
  IF iView THEN
    BROWSER Browser$ URL Url$
    BROWSER Browser$ SHOW
    GOSUB HideFields
  ENDIF
ENDIF
Inspect:
  '---- Continue or return
IF NOT iView THEN Download
prompt$= "Continue?"
Answer$=Input$(iField$, prompt$)
FIELD iField$ BACK COLOR 0,0,1
BROWSER Browser$ HIDE
GOSUB ShowFields 'local subroutine
IF Answer$="n" THEN RETURN ""
DownLoad:
FIELD iField$ BACK COLOR 0,0,1
'---- download binary contents
FIELD iField$ BACK COLOR 0,0,1
Field iField$ TEXT "Loading webpage"
IF NewData THEN
  HTTP Url$ GETDIM Bin
  GET DIM Bin XSIZE size
  IF SIZE<1 THEN RETURN "fail"
  FILE HtmlFile$ WRITEDIM Bin
ENDIF
RETURN HtmlFile$
ShowFields: ' local subroutine
LIST .o$ SHOW
LIST .p$ SHOW
LIST .q$ SHOW
FIELD .pi$ SHOW
FIELD .qi$ SHOW
RETURN ' from local sub
HideFields: ' local subroutine
  LIST .o$ HIDE
  LIST .p$ HIDE
  LIST .q$ HIDE
  FIELD .pi$ HIDE
  FIELD .qi$ HIDE
RETURN ' from local sub
END DEF
''
'r'
DEF NetStatus$(name$)
' by Rbytes, adapted by Dutchman
' Return.level ranges from 0-2
' Usage:
' See https://bit.ly/2Aelgu7 and https://bit.ly/2PHqYzb
' On DNS: https://developers.google.com/speed/public-dns/docs/dns-over-https
DNSurl$="dns.google.com" 'See https://bit.ly/2PHqYzb
' refname$ can be preset to 'url$' with 'NetStatus.refname$=url$'
IF refname$="" THEN refname$=DNSurl$
'
ob=OPTION_BASE()
OPTION BASE 1
' Messages can be overwritten in NetStatus.Msg$()
IF Msg$(1)="" THEN GOSUB Init
'--- Ping with code=80 and code=8080
code=80
DO
  Level=0
  GOSUB Call
   IF code=80 AND Level<3 THEN
    FirstLevel=Level
    code=8080
  ENDIF
UNTIL Level=2 OR code=8080
Level=MAX(Level,FirstLevel)
Status$=Msg$(level+1)
OPTION BASE ob
RETURN Status$ ' reurn from function
'
'----- local subroutine
Call:
Level=PING(TRIM$(name$),code)
IF Level THEN 
  Level+=1
  RETURN
ELSE
  Level=PING(refname$,code)
ENDIF
RETURN ' from subroutine
'---- local subroutine
Init:
DIM Msg$(3)
FOR i=1 TO 3
  READ Msg$(i)
NEXT i
RETURN ' from local subroutine
DATA "Internet connection failed."
DATA "Website is not responding."
DATA "Website is responding."
END DEF
''
'r'
DEF LatestFile$(Dir$,undated$,purge) 
' find latest file with 'Undated$' in name
' if purge=1 then delete older files
File$=""
DIR Dir$ LIST FILES A$,n
FOR i=1 TO n
  IF INSTR(a$(i),undated$,1)=1 THEN File$=a$(i)
NEXT i
IF Purge THEN
  FOR i=1 to n
    IF INSTR(a$(i),undated$,1)=1 AND a$(i)<>File$ THEN FILE Dir$&a$(i) DELETE
  NEXT i
ENDIF
Date$=RIGHT$(Dir$&File$,8)
RETURN File$
END DEF
''
'r'
DEF ISO_Date$  ' modified to allow choice of format
IF .cpref=0 then
  Date$=STR$(CURRENT_YEAR()*10000+100*CURRENT_MONTH()+CURRENT_DATE(),"########")
ELSE
  Date$=STR$(CURRENT_MONTH()*1000000+10000*CURRENT_DATE()+100*CURRENT_HOUR()+ CURRENT_MINUTE(),"########")
'--- Add "T"
  Date$=LEFT$(Date$,4)&"T"&RIGHT$(Date$,4)
ENDIF
ISO_Date$=Date$
END DEF ' ISO_Date$
''
'r'
DEF PageContent$(file$) ' read html-content
FILE file$ SETPOS 0
content$=""
WHILE NOT FILE_END(file$)
  FILE file$ READLINE line$
  content$&=Line$
END WHILE
RETURN content$
END DEF
''
'r'
DEF Input$(Field$,Prompt$)
' Input from buttons
FIELD Field$ BACK COLOR 1,0,0
FIELD Field$ SHOW
FIELD Field$ TEXT Prompt$
BUTTON "yes" SHOW
BUTTON "no" SHOW
T$=""
DO
  IF bp("yes") THEN T$="y"
  IF bp("no") THEN T$="n"
  SLOWDOWN
UNTIL T$<>""
BUTTON "yes" HIDE
BUTTON "no" HIDE
RETURN T$
END DEF
''
'r'
DEF Quicksort$(Array$(,),MaxRow,Rowsize,SortColumn)' for STRINGS
' by Dutchman
' Non-recursive version of the QuickSort algorithm
' This sortfunction operates on a 2-dimensional string-array
' Number of rows is <MaxRow> and number of columns is <RowSize>
' The variable <SortColumn> determines which column is sorted
ShowMaxStack=0 ' will display stack-usage if set to 1
MaxStackPtr=0
DIM SwapRow$(RowSize), Stack1$(30), Stack2$(30)
StackPtr=0 ! HeadPtr=1 ! TailPtr=MaxRow
Qlabel2:
IF HeadPtr>TailPtr THEN
  GOTO Qlabel4
ELSE
  Pivot$= CAPSTR$(Array$((HeadPtr+TailPtr)/2,SortColumn))
  qa=HeadPtr ! qb=TailPtr
  Qlabel1:
  IF CAPSTR$(Array$(qa,SortColumn))<Pivot$ THEN ' while2
    qa=qa+1
    GOTO Qlabel1
  END IF '1
Qlabel3:   
  IF CAPSTR$(Array$(qb, SortColumn))>Pivot$ THEN
    qb=qb-1
    GOTO Qlabel3
  END IF '2
  IF qa<qb THEN
  ' swap rows
    FOR qi=1 TO RowSize
      SwapRow$(qi)=Array$(qa,qi)'save row qa
      Array$(qa,qi)=Array$(qb,qi)'store row qb content in row qa
      Array$(qb,qi)=SwapRow$(qi)'restore content of row qa to row qb
    NEXT qi
    qa=qa+1
    qb=qb-1
    GOTO Qlabel1
   END IF '3
  IF qa=qb THEN
    qq = qb - 1
    qr = qa + 1
  ELSE
    qq = qb
    qr = qa
  END IF '4
  StackPtr = StackPtr + 1
  IF MaxStackPtr<StackPtr THEN
    MaxStackPtr=StackPtr        
  END IF '5      
  qp=HeadPtr
  qs=TailPtr
  IF (qq-qp)<(qs-qr) THEN
    Stack1$(StackPtr)=qr
    Stack2$(StackPtr)=qs
    HeadPtr=qp
    TailPtr=qq
  ELSE
    Stack1$(StackPtr) = qp
    Stack2$(StackPtr) = qq
    HeadPtr = qr
    TailPtr = qs
  END IF '6
  GOTO Qlabel2
END IF '7
Qlabel4:
IF StackPtr > 0 THEN
  HeadPtr = Stack1$(StackPtr)
  TailPtr = Stack2$(StackPtr)
  StackPtr = StackPtr - 1
  GOTO Qlabel2
END IF '8
IF ShowMaxStack THEN
  PRINT "Maximum stacksize=";MaxStackPtr
END IF '9
END DEF ' QuickSort$
' end of Update Currencies code
''
'g'



' shortcut for button press

DEF bp(a$) = BUTTON_PRESSED(a$)


' remove scientific notation before displaying result

DEF format(form$)
  WHILE LEFT$(form$,1)=" " OR LEFT$(form$,1)=","
    form$=RIGHT$(form$,LEN(form$)-1)
    ' trim leading spaces and separators
  ENDWHILE
  IF INSTR (form$, ".") THEN        ' if form$ has a decimal point
    IF NOT numpad.curr THEN
    ' trim trailing zeros
    WHILE RIGHT$(form$,1)="0"
      form$=LEFT$(form$,LEN(form$)-1)
    ENDWHILE
    IF RIGHT$(form$,1)="." THEN
      form$=LEFT$(form$,LEN(form$)-1)
    ENDIF
    ENDIF
  ENDIF
END DEF

'm'

' Settings popup modified for two switches, with labels and text

DEF pw(NAME$,title$,a$,xs,ys,ww,hh,R,G,B,ALPHA)
GRAPHICS CLEAR .9,1,1
PAGE NAME$ SET
PAGE NAME$ SHOW
PAGE NAME$ FRAME xs,ys,ww,hh
PAGE NAME$ COLOR R,G,B,ALPHA
PAGE "" HIDE
FIELD NAME$ TEXT a$ at 20*.rw,50*.rh size 360*.rw,360*.rh ML RO
FIELD NAME$ FONT SIZE 18*.rw
IF .rw<1 THEN lshift=12 ELSE lshift=0
IF title$="Settings" THEN
  if .rw<1 THEN
    FIELD "labels1" TEXT "OFF                   ON" at 112*.rw,255*.rh RO
    FIELD "labels2" TEXT "OFF                   ON" at 112*.rw,388*.rh RO
  ELSE
    FIELD "labels1" TEXT "OFF               ON" at 130*.rw,209*.rh RO
    FIELD "labels2" TEXT "OFF               ON" at 130*.rw,314*.rh RO
  ENDIF
  FIELD "labels1" FONT SIZE 18*.rw
  FIELD "labels2" FONT SIZE 18*.rw
  if .rw<1 THEN
    SWITCH "inter" STATE .view AT 170*.rw-lshift,260*.rh
    SWITCH "cpref" STATE .cpref AT 170*.rw-lshift,388*.rh
  ELSE
    SWITCH "inter" STATE .view AT 170*.rw-lshift,210*.rh
    SWITCH "cpref" STATE .cpref AT 170*.rw-lshift,315*.rh
  ENDIF
ENDIF
FILL ALPHA 0
BUTTON "close" title "❎" AT ww-30,5 SIZE 24,24
FILL ALPHA 1
BUTTON "bottom" title "" AT -6,hh-3 SIZE ww+12,3
BUTTON "left" title "" AT 0,-6 SIZE 3,hh+12*.rh
BUTTON "right" title "" AT ww-3,-6 SIZE 3,hh+12*.rh
BUTTON "upper1" title "" AT -6,0 SIZE ww+12,3
BUTTON "upper2" title "" AT -6,30 SIZE ww+12,3
BUTTON "title" title title$ AT ww/2-50*.rw,3+lshift/2 SIZE 100*.rw,28*.rw
''
'r'
' other UI objects
'
'
END DEF
''

/*
Conversion Data

The technique used to calculate conversions is to choose a reference measure in the middle of the range and set its value to 1. All other measures are then assigned numbers representing the ratio of their value to the reference measure's value.
*/

Categories:
DATA 23 ' number of categories
DATA "Acceleration", "Angle", "Area", "Cooking", Ext.CurrCat$, "Data", "Energy", "Energy Transition"
DATA "Flow Rate", "Frequency", "Illuminance", Ext.EuroCat$, Ext.USDCat$, "Length", "Luminance", "Prefixes", "Power", "Pressure", "Speed",Tscale$, "Time", "Volume", "Weight"

Acceleration:
DATA 7 ' number of items
DATA "Centimeters Per Sec²",0.01 , "Inches per Second²",0.0254 , "Feet per Second²",0.3048 , "Meters Per Second²",1 , "Galileos",0.01 , "Leos",10 , "Gravity",9.80665

Angle:
DATA 9 ' number of items
DATA "Degrees",1 , "Radians",57.2958 , "Gradians",0.9 , "Minutes",0.0166667 , "Seconds",0.000277778 , "Circles",360 , "Quadrants",90 , "Points",11.25 , "Mils",0.05625

Area:
DATA 9 ' number of items
DATA "Acres",4046.86 , "Square Kilometers",1E+06 , "Hectares",10000 , "Square Meters",1 , "Square Centimeters",0.0001 , "Square Miles",2.58999E+06 , "Square Yards",0.836127 , "Square Feet",0.092903 , "Square Inches",0.00064516

Cooking:
DATA 9 ' number of items
DATA "Centiliters",0.35195 , "Cups (CD)",8 , "Fluid Ounces (CD)",1 , "Liters",35.1951 , "Milliliters",0.035195 , "Pints (CD)",20 , "Quarts (CD)",40 , "Tablespoons",0.520421 , "Teaspoons",0.173474

Data:
DATA 8 ' number of items
DATA "Bits",0.000125 , "Bytes",0.001 , "Words",0.008 , "Kilobytes",1 , "Megabytes",1000 , "Gigabytes",1E+06 , "Terabytes",1E+09 , "Petabytes",1E+12

Energy:
DATA 12 ' number of items
DATA "BTU",251.996 , "Calories",1 , "Cubic Mile of Oil",3.83347E+19 , "Foot Pounds",0.324048 , "Horsepower Per Hr",641616 , "Joules",0.239006 , "KiloJoules",239.006 , "KiloCalories",1000 , "Kilowatt Hours",860421 , "Kilotons",1E+12 , "MegaJoules",239006 , "Therms (US)",2.52104E+07

EnergyTransition:
DATA 28 ' number of items
DATA "Watt",1 , "Kilowatt",1000 , "Kwh/y",0.114077 , "Kg/y Coal",0.746571 , "Kg/y Brown coal",0.475321 , "Kg/y Peat dry",0.475321 , "Kg/y Wood",0.475321 , "Kg/y Fat",1.17246 , "Kg Battery Li-Po Li-Hv",0.0570386 , "m² Solar panel",31.6564 , "Liter/y petrol",1.08373 , "Liter/y diesel oil",1.22316 , "Liter/y heating oil",1.18197 , "Liter/y Hydrogen 700bar",0.29058 , "Liter/y Alcohol",0.741501 , "Liter/y LNG",0.703476 , "Liter/y LPG",0.814384 , "Liter/day heating oil",431.713 , "Liter/day LNG",256.944 , "Liter/day LPG",297.454 , "m³/y natural gas",1.23425 , "m³/y natural gas NL",1.05838 , "m³/y Hydrogen",0.5357 , "m³/day natural gas",450.81 , "m³/day natural gas NL",386.574 , "m³/day Hydrogen",195.664 , "m³/day water to ice",3865.74 , "g/y Thorium",2516.67

FlowRate:
DATA 17 ' number of items
DATA "Cubic Meters per Sec",951019 , "Cubic Meters per Min",15850.3 , "Cubic Meters per Hour",264.172 , "Liters per Second",951.019 , "Liters per Minute",15.8503 , "Liters per Hour",0.264172 , "Cubic Feet per Sec",26929.9 , "Cubic Feet per Minute",448.831 , "Cubic Feet per Hour",7.48052 , "Gallons (US) per Sec",3600 , "Gallons (US) per Min",60 , "Gallons (US) per Hour",1 , "Gallons (US) per Day",0.0416667 , "Gallons (UK) per Sec",4323.42 , "Gallons (UK) per Min",72.057 , "Gallons (UK) per Hour",1.20095 , "Gallons (UK) per Day",0.0500396

Frequency:
DATA 23
DATA "1/second" ,"1" ,"ac power" , "60" ,"cycle/second" ,"1" ,"degree/hour" ,"7.7160493827e-7" ,"degree/minute" ,".0000462962962961" ,"degree/second" ,".0027777777778" ,"dentist drill" ,"6666.6666668","gigahertz" ,"1.0e+9" ,"hertz" ,"1" ,"kilohertz" ,"1000" ,"megahertz" ,"1.0e+6" ,"middle c", "261.625565" ,"millihertz" ,".001 " ,"radian/hour" ,".000044209706621" ,"radian/minute" ,".0026525823738" ,"radian/second" ,".15915494327" ,"red light" ,"4e+14" ,"revolution/hour" ,".00027777777778" ,"revolution/minute" , ".016666666667" ,"revolution/second" ,"1" ,"RPM" ,".016666666667" ,"terahertz", "1e+12", "violet light", "8e+14"

Illuminance:
DATA 11 ' number of items
DATA "Footcandles",1 , "Kilolux",92.903040144 , "Lumen/cm²",929.03040144 ,"Lumen/ft²", 1 , "Lumen/in²",144 , "Lumen/meter²",.092903040144 , "Lux", .092903040144 ,"Metercandles" ,.092903040144 ,"Milliphot" ,.92903040144 ,"Nox" , .000092903040144 ,"Phot" ,929.03040144

Length:
DATA 13 ' number of items
DATA "Ångströms",1E-08 ,"Centimeters",1 , "Fathoms",182.88 , "Feet",30.48 , "Furlongs (US)",20116.8 , "Inches",2.54 , "Kilometers",100000 , "Meters",100 ,"Mils",0.00254 , "Miles",160934 , "Millimeters",0.1 , "Nanometers",1E-07 , "Yards",91.44

Luminance:
DATA 15
DATA "Apostilb" ,".029571957588" ,"Blondel" ,".029571957588" ,"Candela/cm²" ,"929.03043597" ,"Candela/foot²" ,"1" , "Candela/inch²" ,"144" ,"Candela/meter²" ,".092903043597" ,"Footlambert" ,".31830989854" ,"Kilocandela/cm²" ,"929030.43597" ,"Kilocandela/foot²" ,"1000" ,"Kilocandela/inch²" ,"144000" ,"Kilocandela/meter²" ,"92.903043597" ,"Lambert" ,"295.71957588" ,"Millilambert" ,".29571957588" ,"Nit", ".092903043597" ,"Stilb" ,"929.03043597"

Power:
DATA 14 ' number of items
DATA "Watts",1 ,"Kilowatts",1000 , "Megawatts",1E+06 , "Gigawatts",1E+09 , "Terawatts",1E+12 , "KWh/year",1000 , "MegaJoule/year (MJ/y)",1E+06 ,"Horsepower (IT)",745.7 , "Horsepower (Metric)",756.042 , "Moosepower",2438.44 , "Calories per Hour",0.0011629 , "BTU per Hour",2.93071E+09 , "Foot Pounds per Hr",3.76616E+09 , "Tons Refrigeration",3516.8

Prefixes:
DATA 21 ' number of items
DATA "yotta",1E+24 , "zetta",1E+21 , "exa",1E+18 , "peta",1E+15 , "tera",1E+12 , "giga",1E+09 , "mega",1E+06 , "kilo",1000 , "hecto",100 , "deca",10 , "none",1 , "deci",0.1 , "centi",0.01 , "milli",0.001 , "micro",1E-06 , "nano",1E-09 , "pico",1E-12 , "femto",1E-15 , "atto",1E-18 , "zepto",1E-21 , "yocto",1E-24

Pressure:
DATA 13 ' number of items
DATA "Bars",1000 , "Millibars",1 , "Pascals",0.01 , "HectoPascals",1 , "KiloPascals",10 , "MegaPascals",10000 , "Atmospheres",1013.25 , "Pounds per Sq. Foot",0.478803 , "Pounds per Sq. Inch",68.9476 , "Inches of Water",2.49089 , "Inches of Mercury",33.864 , "Centimeters of Water",0.980665 , "Centimeters of Mercury",13.3323

Speed:
DATA 11 ' number of items
DATA "Feet per Second",1.09728 , "Feet per Minute",0.018288 , "Furlongs per Fortnight",0.000598715 , "Inches per Second",0.09144 , "Kilometers per Hour",1 , "Kilometers per Sec.",3600 , "Knots",1.852 , "Miles per Hour",1.60935 , "Miles per Second",5793.64 , "Speed of Light",1.07925E+09 , "Speed of Sound",1225.04

Temperatures:
DATA 8 ' number of items
' values are used as measure-pointer
DATA "Celsius [°C]",1 , "Delisle [°D]",5 , "Fahrenheit [°F]",3 , "Kelvin [K]",2 , "Newton [°N]",6 , "Rankine [°Ra]",4 , "Réamur [°Re]",7 , "Rømer [°Rø]",8

Timing:
DATA 10 ' number of items
DATA "Milliseconds",1.66667E-05 , "Seconds",0.0166667 , "Minutes",1 , "Hours",60 , "Days",1440 , "Weeks",10080 , "Fortnights",20160 , "Months",43800 , "Years",525600 , "Leap Years",527040

Volume:
DATA 12 ' number of items
DATA "Cubic Centimeters",1 , "Cubic Feet",28316.8 , "Cubic Inches",16.3871 , "Cubic Yards",764554 , "Cups (CD)",284.131 , "Fluid Ounces (CD)",28.4131 , "Gallons (CD)",4546.09 , "Gallons (US)",3785.41 , "Liters",1000 , "Milliliters",1 , "Pints (CD)",568.261 , "Quarts (CD)",1136.52

Weight:
DATA 10 ' number of items
DATA "Grams",0.00220462 , "Kilograms",2.20462 , "Ounces",0.0625 , "Ounces (troy)",0.0685714 , "Pounds",1 , "Grains",10 , "Tonnes (metric)",2204.62 , "Tons (US short)",2000 , "Long Tons (UK)",2240 , "Stones",14

TBA:
DATA 10 ' number of items
DATA "To Be Added",1 ,"",1 ,"",1 ,"",1 ,"",1 ,"",1 ,"",1 ,"",1 ,"",1 ,"",1
Attachments
loader.GIF
loader.GIF (75.22 KiB) Viewed 65 times
iconvert3.GIF
iconvert3.GIF (222.71 KiB) Viewed 65 times
iconvert3.PNG
iconvert3.PNG (14.12 KiB) Viewed 65 times
E9B2035D-EFF3-407A-93B2-678E0C04D125.png
E9B2035D-EFF3-407A-93B2-678E0C04D125.png (295.52 KiB) Viewed 107 times
Last edited by rbytes on Mon Dec 03, 2018 11:55 am, edited 8 times in total.
####### Living the colorful life #######

User avatar
Dutchman
Posts: 853
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: iConvert 5.3

Post by Dutchman » Tue Nov 27, 2018 7:21 pm

Message removed.
Problem solved.
Last edited by Dutchman on Mon Dec 03, 2018 7:38 pm, edited 1 time in total.
We consider it a refreshing mental exercise to figure out ways to circumvent foolishness (Quote from Richard)

User avatar
rbytes
Posts: 1795
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 5.3

Post by rbytes » Tue Nov 27, 2018 7:45 pm

Some errors crept into Frequency conversions.
I will take the code offline until later today.
*****************************************************
6 hours later...
The code is back online with corrected Frequency conversion units and some new measures added. The high-speed dental drill may be of interest. Also the two color frequencies, red and violet, which occupy the extremes of visible light. Note that the entire visible spectrum covers just one octave. Yet the range of human hearing (optimum) covers 10 octaves. Try to imagine a world where those realities were reversed!

The code used in iConvert for simple ratios automatically calculates the inverse when the measures are exchanged. The problem was that in some of the conversions, I had used a wrongly inverted value to begin with! I hope the newly-posted version of iConvert 5.3 will have no errors, but in coding there are never guarantees! ;)
####### Living the colorful life #######

User avatar
GeorgeMcGinn
Posts: 417
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro
IMac
Location: Venice, FL
Flag: United States of America
Contact:

Re: iConvert 5.3

Post by GeorgeMcGinn » Sun Dec 02, 2018 9:45 pm

I know you guys are doing a ton of work on this program, as I'm doing a lot of work to get the astronomy and cosmology physics stuff done to add to this program, but this version is asking for a loader.gift file and I have no idea where to find it. It never appeared in any other version that I'm aware of and I have downloaded most if not all versions of this program.

So I need to know if version 5.3 is the most recent version or if the version 5 is the most recent version. From my point of you there seems to be two different programs out here, and I think they may need to be a post that has a definite language that says this is the current version and has all the graphic files associated with it loaded in the post, otherwise it's confusing as to which version I'm to use.

I'm working on creating two categories: Astronomy or cosmology, which will cover the basic astronomy and Cosmology conversions, and astrophysics, or physics, that will cover all the conversions done in physics. I may qualify it as astrophysics only because physics exists in other fields of study. Electrical engineering has its own physics field, which I believe you've got most of them in your frequencies and your electronic conversions. And you'll find that most of the physics conversions can also apply to like fluid dynamics and earth sciences to name a couple of other fields that may have conversion factors.
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)
http://georgemcginn.wordpress.com
http://cosmologyandspace.wordpress.com

User avatar
GeorgeMcGinn
Posts: 417
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro
IMac
Location: Venice, FL
Flag: United States of America
Contact:

Re: iConvert 5.3

Post by GeorgeMcGinn » Sun Dec 02, 2018 9:53 pm

OK I found the loader.GIF file in the iConvert 4 Beta post.

However after loading this file and running the I convert version 5.3 I now get a run time error on the following statement:

DIR Dir$ LIST FILES A$,n

I have no idea if this is something new or or what but I've not gotten this error in any other versions of the iConvert program.
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)
http://georgemcginn.wordpress.com
http://cosmologyandspace.wordpress.com

User avatar
rbytes
Posts: 1795
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 5.3

Post by rbytes » Sun Dec 02, 2018 10:00 pm

George, I agree that the attachments, now including "loader.GIF", should be posted with each major upgrade. So I have now added them to the first post in this thread, along with the 5.3 code. There are 3 files that need to be installed at the same location as the program - iConvert3.PNG, iConvert3.GIF and loader.GIF.

The code line you quoted is part of a function that purges old .html downloads of currency data. There must be a condition that wasn't anticipated. My guess is that the line is looking in the Data folder to list the contents and is finding it empty. That could be the case when running this version for the first time. Try copying ANY file into the Data folder. Then run the program and see if that solves the issue.

If not, we will have to wait for Ton to do further troubleshooting. He created the code for the Currency category and is the expert on how it should function.
####### Living the colorful life #######

User avatar
rbytes
Posts: 1795
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 5.3

Post by rbytes » Mon Dec 03, 2018 3:17 am

George: However after loading this file and running the I convert version 5.3 I now get a run time error on the following statement:

DIR Dir$ LIST FILES A$,n
I was able to duplicate the problem. If iConvert 5.3 is run before a Data folder is created, it fails with that exact error. If a user first creates a Data folder, no error occurs.

But I suggest that the logic within the program be changed so that it checks for a Data folder and creates one if it doesn't exist, before trying to purge old .html files.

Neither Ton nor I got this error because we were continuing to use the Data folder that was created by an earlier version of iConvert.
####### Living the colorful life #######

User avatar
GeorgeMcGinn
Posts: 417
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro
IMac
Location: Venice, FL
Flag: United States of America
Contact:

Re: iConvert 5.3

Post by GeorgeMcGinn » Mon Dec 03, 2018 11:21 am

Thanks. I'll create the folder so that I can continue running 5.3.

I agree that the program would run much smoother to actually check and create the directory if it doesn't exist first.

And this is for those who are beginning programmers and are writing code, that in all kinds of programming including mainframe in PC programming, we try to minimize the error messages by anticipating the kinds of problems that you would run into. It may lengthen your program a little bit, and add a little more complexity to your code, but you'll benefit in the long run when users have less problems with a buggy app and will appreciate how enjoyable it is to use.

Richard and Dutchman, the above is not directed at you but I wanted to put something in to help those who are looking and just reading your posts to educate them a little bit on programming and in dissipating all kinds of errors that could happen in your code.




rbytes wrote:
Mon Dec 03, 2018 3:17 am
George: However after loading this file and running the I convert version 5.3 I now get a run time error on the following statement:

DIR Dir$ LIST FILES A$,n
I was able to duplicate the problem. If iConvert 5.3 is run before a Data folder is created, it fails with that exact error. If a user first creates a Data folder, no error occurs.

But I suggest that the logic within the program be changed so that it checks for a Data folder and creates one if it doesn't exist, before trying to purge old .html files.

Neither Ton nor I got this error because we were continuing to use the Data folder that was created by an earlier version of iConvert.
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)
http://georgemcginn.wordpress.com
http://cosmologyandspace.wordpress.com

User avatar
rbytes
Posts: 1795
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 5.3a

Post by rbytes » Mon Dec 03, 2018 12:00 pm

Thanks, George. the iConvert 5.3 code has been replaced with 5.3a. Ton has modified the logic so that if the Data folder is missing, it is created before the code line is encountered that needs to do a DIR of it.

You make a good point for program testing - to always duplicate the conditions that will be encountered in a clean install. I will modify my sections of code in the next version so that if images or animations are missing, iConvert will still run, but will pop up a message listing the missing files.
####### Living the colorful life #######

User avatar
GeorgeMcGinn
Posts: 417
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro
IMac
Location: Venice, FL
Flag: United States of America
Contact:

Re: iConvert 5.3a

Post by GeorgeMcGinn » Tue Dec 04, 2018 7:49 pm

That's actually a great idea for missing graphics. I know for the Internet, a lot of people would turn graphics off to speed up download times, so most images had alt-text field in place of the graphics. This was something that was implemented during the dial up days and when it cost a dollar a minute in Europe for Internet access. In these situations of nobody really wanted to see the graphics unless they were absolutely necessary.

So rather than a message saying graphic is missing you could just say in text "iConvert Version 5.3" make it something meaningful. You can put something in a little softer instead of saying missing graphics say "in place of graphic."

In fact, if the graphic is missing you could just change the else to put in a large title instead and not even let people to know that a graphic is missing. If you plan on putting this app on iTunes, then It wouldn't make a difference whether it was a graphics or text for they wouldn't know the difference.

But those of us who have access to the source code can see that there should have been a graphics and we could go look for it.


rbytes wrote:
Mon Dec 03, 2018 12:00 pm
Thanks, George. the iConvert 5.3 code has been replaced with 5.3a. Ton has modified the logic so that if the Data folder is missing, it is created before the code line is encountered that needs to do a DIR of it.

You make a good point for program testing - to always duplicate the conditions that will be encountered in a clean install. I will modify my sections of code in the next version so that if images or animations are missing, iConvert will still run, but will pop up a message listing the missing files.
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)
http://georgemcginn.wordpress.com
http://cosmologyandspace.wordpress.com

Post Reply