diff --git a/README.md b/README.md index 7cb14243b8503e9c6dff66151e9c6ed2ec41127a..5cd0f722df2c86302e9bbe6e4c109614aaae8a87 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,12 @@ This is in csv format. For gnuplot, do not forget to `set datafile separator ',' # BUGS ## Real Bugs -Only under windows: I use os.Create() to open a file for writing. In my "Documents" folder, the function call returns "The system cannot find the file specified". Note, this is when creating a file, not opening an existing one. I do not have any error when I run the program from a different directory. I did experiment with chmod() on the directory, but this (a) did not do anything and (b) only the bits set by 0200 are actually affected according to go's documentation. +### Only under windows +I use `os.Create()` to open a file for writing (plots, `.csv` files. In my "Documents" folder, the function call returns "The system cannot find the file specified". On my test machine, this was a result of trying to write to a protected folder with an application (ackley_mc) that windows did not know about. If you fight your way through the windows menus, you will find a place that shows "blocked software". You could add `ackley_mc.exe` to the list of blessed executables, but why not just run the code from another directory? ## Non bugs -The UI toolkit is "fyne". It does not do charts, so we use go-chart which makes a png, which we can store in memory and feed to the fyne toolkit. Unfortunately, an svg file from go-chart causes fyne to choke. This means we are stuck with png. One day, one should try out the charting library which is based on fyne. +The UI toolkit is "fyne". It does not do charts, so we use go-chart which makes a png, which we can store in memory and feed to the fyne toolkit. We can ask go-chart to make an svg file, but this causes fyne to choke. This means we are stuck with png. One day, one should try out the charting library which is based on fyne. The graphical interface follows no known style convention and looks like it was designed by a three-year old. diff --git a/mc_work/dorun.go b/mc_work/dorun.go index 1b6a384a81ae92e6b249b5b41024ac9d274c2408..fe78a58b78eb6bcc7a08cd466dc55009f2ee5e45 100644 --- a/mc_work/dorun.go +++ b/mc_work/dorun.go @@ -4,10 +4,8 @@ package mcwork import ( "bufio" "bytes" - "errors" "fmt" "io" - "io/fs" "math" "math/rand" "os" @@ -65,48 +63,31 @@ func isNotSane(mcPrm *McPrm) error { return nil } -// fExists returns true if the file exists. -// It is part of the exercise, working around file permissions on windows -func fExists(name string) bool { - var err error - if _, err = os.Stat(name); err == nil { - return true - } - if errors.Is(err, fs.ErrNotExist) { - return false - } - return true -} - -// createFix is a wrapper around os.Create() which I seem to need for windows. -// On windows, this fails if I am in my "Documents" directory. +// createFix is a wrapper around os.Create() with a long error message. +// On windows, this fails if I am in my "Documents" directory due to +// its ransomware protection. func createFix(name string) (*os.File, error) { - longErr := `%s does not exist, but could not create it: + emsg := `Could not create "%s". The error was %w -Please run the program from somewhere other than %s` - existErr := `File exists, but unable to write to it: -%w` +This is probably a permission error. Specify a directory other than +%s +and try again. It might be your protected folder settings.` + var t string + var err, e2 error var f *os.File - var err error if f, err = os.Create(name); err == nil { return f, nil // Most common path (no problem) } - if !fExists(name) { // does not exist, but we have a problem. - var d string - if t, e := filepath.Abs(name); e != nil { - return nil, fmt.Errorf("cannot work out path %w", e) - } else { - d = filepath.Dir(t) - } - if _, e := os.Stat(d); e != nil { - return nil, fmt.Errorf("parent directory %s is broken %w", d, err) - } - return nil, fmt.Errorf(longErr, name, err, d) + + if t, e2 = filepath.Abs(name); e2 != nil { + return nil, fmt.Errorf("The path for %s is broken: \"%w\"", name, e2) } - return nil, fmt.Errorf(existErr, err) // The file exists.. + + return nil, fmt.Errorf(emsg, name, err, filepath.Dir(t)) } -// setupRun does things like get the cooling rate, seed the random numbers. +// setupRun does things like get the cooling rate, seed the random numbers, +// open files for writing output. func setupRun(mcPrm *McPrm, cprm *cprm) error { var err error cprm.rand = rand.New(rand.NewSource(int64(getSeed()))) @@ -139,7 +120,7 @@ func setupRun(mcPrm *McPrm, cprm *cprm) error { return fmt.Errorf("broke setting plot filename: %w", err) } if cprm.fplotWrt, err = os.Create(mcPrm.fPltName); err != nil { - return fmt.Errorf ("Trying to create file: %w", err) + return fmt.Errorf("Trying to create file: %w", err) } } else { // Must be writing to a screen var w bytes.Buffer // could be fancier. Preallocate and use bytes.Newbuffer diff --git a/mc_work/unwanted.goat b/mc_work/unwanted.goat index 707f4fc6e156f6c2dff9758ada18d8810f97908f..094f87f6b37c2d90669728642ced58f9b998e335 100644 --- a/mc_work/unwanted.goat +++ b/mc_work/unwanted.goat @@ -7,3 +7,17 @@ func alt_newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) { xT[i] = x + t } } + + +// fExists returns true if the file exists. +// It is part of the exercise, working around file permissions on windows +func fExists(name string) bool { + var err error + if _, err = os.Stat(name); err == nil { + return true + } + if errors.Is(err, fs.ErrNotExist) { + return false + } + return true +} diff --git a/ui/input_tab.go b/ui/input_tab.go index 64b074a9af302ac24a92cd1412067ae0f71261a3..8f0a3255b7603c1919583856b94c5c8bed0a334e 100644 --- a/ui/input_tab.go +++ b/ui/input_tab.go @@ -21,7 +21,7 @@ import ( "example.com/ackley_mc/mc_work" ) -// startrun is what happens when you click on the form's button to start +// startrun is called when you click on the form's button to start // a calculation. func startrun(genParams genParams, form *widget.Form, mcPrm *mcwork.McPrm) { form.Disable() @@ -164,7 +164,6 @@ func getmcprm(rd fyne.URIReadCloser, err error, genParams genParams, reload func } // rdwork is called after the file open dialog gets "OK" -//func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, reload func()) { func rdwork(genParams genParams, reload func()) { getter := func(rd fyne.URIReadCloser, err error) { getmcprm(rd, err, genParams, reload) @@ -176,7 +175,7 @@ func rdwork(genParams genParams, reload func()) { t.SetLocation(y) // If there was an error, we just use default location } } - t.Show() // set an error and see if anybody notices + t.Show() } // mcWrap is run in the background so the interface does not block.