how to run .fsx in fsi - f#

Exploring F# with FSharp.Charting I thought I would start with a simple 'hello world' but it leaves me with more questions then lines of code.
#load #"..\packages\FSharp.Charting.0.90.14\FSharp.Charting.fsx"
open FSharp.Charting
let chart = Chart.Line([ for x in 0 .. 10 -> x, x*x ])
chart.ShowChart()
chart.SaveChartAs(#"C:\Temp\chart.png",ChartTypes.ChartImageFormat.Png)
This works in interactive window in VS, but what I want to do is execute this script from the cmd line (using fsi.exe). I made an association with fsx files to fsi, but when I execute it it opens fsi but no chart is created. What do I need to do?

Short answer: add the following line at the end of your program:
System.Windows.Forms.Application.Run()
Long answer:
The chart does get created, but it immediately disappears, because your program immediately exits, right after creating the chart. This does not happen in the F# Interactive window in Visual Studio, because the F# interactive window doesn't close immediately after executing your program - it just hangs out there, waiting for you to submit more code for execution.
In order to make your program not exit immediately, you could implement some waiting mechanism, such as waiting for a set amount of time (see System.Threading.Thread.Sleep) or waiting for the user to press Enter (via stdin.ReadLine()), etc.
However, this won't actually help you, because there is the next problem: the chart is drawn via Windows Forms, which relies on the message loop running - otherwise the window can't receive messages, and so can't event paint itself.
FSI does have its own built-in event loop, and this is how your program works under VS. However, if you implement a "waiting" mechanism (e.g. stdin.ReadLine()), this event loop will be blocked - won't be able to pump messages. Therefore, the only sane way to keep your program from exiting, while not interfering with the functioning of the chart window, is to start your own event loop. And this is exactly what Application.Run() does.
Saving to disk without displaying:
(in response to comment)
From what I understand, the FSharp.Charting library was intended as a quick-and-dirty way to display charts on the screen, primary use case being exploring datasets live within F# Interactive. More specifically, some key properties of the Chart object, such as ChartAreas and Series are not initialized upon chart creation, but only when it is shown on the screen (see source code), and without these properties the chart remains empty.
Short of submitting a pull request to the library, I recommend dropping down to the underlying System.Windows.Forms.DataVisualization.Charting.Chart:
open System.Windows.Forms.DataVisualization.Charting
let ch = new Chart()
ch.ChartAreas.Add( new ChartArea() )
let s = new Series( ChartType = SeriesChartType.Line )
s.Points.DataBind( [for x in 1..10 -> x, x*x], "Item1", "Item2", "" )
ch.Series.Add s;
ch.SaveImage(#"C:\Temp\chart.png", System.Drawing.Imaging.ImageFormat.Png)

Related

Vala Print Output Visible in Terminal only after Window is Closed

I am learning vala (after a couple years of Java) and I have this very simple code, just to make a few tests :
button_2.clicked.connect (() => {
string test = "hello";
stdout.printf (test);
});
It is a Gtk.Window class, and when I run it and click the button, say five times, nothing happens.
Then, when I close the window, all five print outputs appear together in the terminal.
hellohellohellohellohello
In a Java application, after each click of a button, the output individually shows in the terminal.
I wonder why a Vala app doesn't print while the window is open, and if there is a way around it.
Output is being buffered. Insert a newline, or call stdout.flush().

Can Dataflow sideInput be updated per window by reading a gcs bucket?

I’m currently creating a PCollectionView by reading filtering information from a gcs bucket and passing it as side input to different stages of my pipeline in order to filter the output. If the file in the gcs bucket changes, I want the currently running pipeline to use this new filter info. Is there a way to update this PCollectionView on each new window of data if my filter changes? I thought I could do it in a startBundle but I can’t figure out how or if it’s possible. Could you give an example if it is possible.
PCollectionView<Map<String, TagObject>>
tagMapView =
pipeline.apply(TextIO.Read.named("TagListTextRead")
.from("gs://tag-list-bucket/tag-list.json"))
.apply(ParDo.named("TagsToTagMap").of(new Tags.BuildTagListMapFn()))
.apply("MakeTagMapView", View.asSingleton());
PCollection<String>
windowedData =
pipeline.apply(PubsubIO.Read.topic("myTopic"))
.apply(Window.<String>into(
SlidingWindows.of(Duration.standardMinutes(15))
.every(Duration.standardSeconds(31))));
PCollection<MY_DATA>
lineData = windowedData
.apply(ParDo.named("ExtractJsonObject")
.withSideInputs(tagMapView)
.of(new ExtractJsonObjectFn()));
You probably want something like "use an at most a 1-minute-old version of the filter as a side input" (since in theory the file can change frequently, unpredictably, and independently from your pipeline - so there's no way really to completely synchronize changes of the file with the behavior of the pipeline).
Here's a (granted, rather clumsy) solution I was able to come up with. It relies on the fact that side inputs are implicitly also keyed by window. In this solution we're going to create a side input windowed into 1-minute fixed windows, where each window will contain a single value of the tag map, derived from the filter file as-of some moment inside that window.
PCollection<Long> ticks = p
// Produce 1 "tick" per second
.apply(CountingInput.unbounded().withRate(1, Duration.standardSeconds(1)))
// Window the ticks into 1-minute windows
.apply(Window.into(FixedWindows.of(Duration.standardMinutes(1))))
// Use an arbitrary per-window combiner to reduce to 1 element per window
.apply(Count.globally());
// Produce a collection of tag maps, 1 per each 1-minute window
PCollectionView<TagMap> tagMapView = ticks
.apply(MapElements.via((Long ignored) -> {
... manually read the json file as a TagMap ...
}))
.apply(View.asSingleton());
This pattern (joining against slowly changing external data as a side input) is coming up repeatedly, and the solution I'm proposing here is far from perfect, I wish we had better support for this in the programming model. I've filed a BEAM JIRA issue to track this.

Move execution point in Xcode/lldb

Is there a way to set the execution point while debugging Xcode/lldb? To be more specific, after hitting a breakpoint, moving the execution point manually to another line of code?
If you're looking at moving it up or down with in a method you can click and drag the green arrow to a specific point. so if you want to back up a line before the breakpoint. click on the green arrow that is produced and drag it up. If you hit run you'll hit your breakpoint again
In Xcode 6, you can use j lineNumber - see documentation below:
(lldb) help j
Sets the program counter to a new address. This command takes 'raw' input
(no need to quote stuff).
Syntax: _regexp-jump [<line>]
_regexp-jump [<+-lineoffset>]
_regexp-jump [<file>:<line>]
_regexp-jump [*<addr>]
'j' is an abbreviation for '_regexp-jump'
One of the great things about lldb is that it's easy to extend it with a little bit of python scripting. For instance, I threw together a new jump command without much trouble:
import lldb
def jump(debugger, command, result, dict):
"""Usage: jump LINE-NUMBER
Jump to a specific source line of the current frame.
Finds the first code address for a given source line, sets the pc to that value.
Jumping across any allocation/deallocation boundaries (may not be obvious with ARC!), or with optimized code, quickly leads to undefined/crashy behavior. """
if lldb.frame and len(command) >= 1:
line_num = int(command)
context = lldb.frame.GetSymbolContext (lldb.eSymbolContextEverything)
if context and context.GetCompileUnit():
compile_unit = context.GetCompileUnit()
line_index = compile_unit.FindLineEntryIndex (0, line_num, compile_unit.GetFileSpec(), False)
target_line = compile_unit.GetLineEntryAtIndex (line_index)
if target_line and target_line.GetStartAddress().IsValid():
addr = target_line.GetStartAddress().GetLoadAddress (lldb.target)
if addr != lldb.LLDB_INVALID_ADDRESS:
if lldb.frame.SetPC (addr):
print "PC has been set to 0x%x for %s:%d" % (addr, target_line.GetFileSpec().GetFilename(), target_line.GetLine())
def __lldb_init_module (debugger, dict):
debugger.HandleCommand('command script add -f %s.jump jump' % __name__)
I put this in a directory where I keep Python commands for lldb, ~/lldb/, and I load it in my ~/.lldbinit file with
command script import ~/lldb/jump.py
and now I have a command jump (j works) which will jump to a given line number. e.g.
(lldb) j 5
PC has been set to 0x100000f0f for a.c:5
(lldb)
This new jump command will be available both in command-line lldb and in Xcode if you load it in your ~/.lldbinit file -- you'll need to use the debugger console pane in Xcode to move the pc instead of moving the indicator in the editor window.
You can move the program counter (pc) in lldb using the lldb command register write pc. But it's instruction based.
There's an excellent lldb/gdb comparison here that is useful as an lldb overview.

Help embedding FSI

Starting here - Embedding F# interactive - I've been trying to embed FSI in my application.
However, I'm getting weird stuff back from StandardOutput.
for example, in standard FSI, if I send this:
let a = 3;;
I get this back:
[empty line here]
val a : int = 3
[empty line here]
> |
(with Pipe representing the input position)
But if I send let a = 3;; to StandardInput, I get this back on StandardOutput:
>
val a : int = 3
|
Has anyone else tried this? Is there something I'm doing wrong, and if not is there any way to work around this? None of the things I've tried so far work, and before I try the 'worse' thing I can think of (set a timer after sending stuff, add the > myself on timeout), I'd like to know if there is a better way!
When embedding F# Interactive, Visual Studio uses the --fsi-server:<some value> parameter.
As far as I know, this does two things:
Changes the way output is printed (instead of printing >, it prints SERVER-PROMPT> on a separate line, so it should be easier to remove it from the output and detect state when input is expected)
It also starts some .NET Remoting channel that you can use to stop execution of commands in F# Interactive (e.g. if it runs into an infinite loop) and it can also provide some completion information.
The F# Interactive pad in MonoDevelop F# plugin uses the flag (see source code on GitHub). I think it works mostly right, but I believe it sometimes prints additional \n in the output.

ERLANG - wxGrid register

Im having some trouble with the erlang wx module.
My program runs as follows:
Server = wx:new(),
Frame = wxFrame:new(Server, -1, "" [{size,{700, 600}}]), %%%REFERENCE TO WINDOW
Panel = wxPanel:new(Frame), %%% REF TO PANEL IN FRAME
Then I pass Panel to another process and try to create a Grid
XreportZ = wxGrid:new(Panel, 24, [ {pos, {0,0}} , {style, 1}] ),
The problem occurs when I pass panel, erlang says that the object Panel becomes invalid outside of its local process. So how is it that I can reference Panel outside of the function that spawned it. I do not believe register can be used for this. I belive the answer lies somewhere is referencing the Server and getting back the Panel ID.
To date I still can find no answer.
Did You try "wx:get_env/0"?
I am not too deep inside wxErlang/wxWidgets, but maybe this could be a start...

Resources