Smalltalk (Pharo) How to interface with the user simply - console-application

I stumbled upon Smalltalk and further downloaded Pharo, because it was recommended. My first impression is very positive. I wanted to port some simple programs I have written in C++ (my main language), so I can get a feel for Smalltalk.
However, I realized I can't find a simple way to just get some input from the user, e.g. I want to create a console calculator with a REPL loop, but I can't find a way to do this in Pharo. I don't want a gui with buttons, because that is just slow and inconvenient.
Could someone please point out to me how to do simple stuff in Smalltalk, like have the user enter 10 numbers or a command etc.? Do I have to use a different implementation? I'm aiming at std::cin/cout or python's print/input
I know Transcript show:, but that only covers the output portion.
Thanks in advance!

Getting input from the user is easy, but emulating a line-based console not so much. At least it would be more cumbersome than relying on the GUI, which is not really so slow and inconvenient after all.
The closest input equivalent to Transcript show: would be:
UIManager default request: 'Title of the request'
If you mark this snippet and "print it" or "inspect it", you will see a prompt dialog and can type something into it. When you accept the dialog with OK or return, you will get the entered String back as the return value of request:.
Getting ten numbers could be done like this:
(1 to: 10) collect: [:each | (UIManager default request: 'Enter number ', each asString) asNumber ]
The result will be an Array of the entered numbers.
Or, without using collect: and building up the collection yourself:
numbers := OrderedCollection new.
10 timesRepeat:
[ numbers add: (UIManager default request: 'Enter next number') asNumber ].
numbers do: [:each | Transcript show: each ].
You might also like UIManager default chooseFrom:. Browse the UIManager class and try out the various methods.
Note that Pharo's playground (called workspace in most other Smalltalks) already does what a REPL does, albeit it is not limited to line-based input. You can type Smalltalk expressions, evaluate them and have the results printed there. I am aware that this information does not give you the experience of porting your calculator app from C++. But I guess the way how the I/O works, or rather the interaction with the user, is not the essence of the programs you are trying to port, right? So you might as well write a class Calculator, in which you implement your calculator app, taking a String as input and returning the resulting number, and then invoke it from the playground by evaluating an expression like the following:
Calculator new calculate: '3 + 4'
If you really, really want to stick to console stuff and miss the benefits of the usual Smalltalk IDE and the experience of learning and using it, you might be better off with GNU Smalltalk. I think there are ways to create console applications with Pharo as well, but I would not recommend that to Smalltalk newcomers and I will leave that answer to someone who has already done it once.

You can use Pharo and get immediate feedback from the terminal like this:
➜ ./pharo Pharo.image eval "6+5"
11
Whatever you have between these quotes is being used as source by the compiler and the answered object will be printed to the stdout. In that example, it will be using SmallInteger>>asString behind the scenes.
For making a REPL, you don't need a lot. If you want to take a look, I've made REPLEndpoint using the Zinc HTTP server. In REPLEndpoint >> post you'll find the part where it uses the snippet you send to be evaluated:
snippet := '6+5'.
answer := OpalCompiler new evaluate: snippet.
answer
And answer will be the 11 SmallInteger instance you'd expect.
For additional hints on how your command line based REPL, take a look at the EvaluateCommandLineHandler class as it implements the basic step of what a REPL would do.

Related

Prompt user to fill in a template?

I've never been able to find anything about this in any language, but what I want to do seems rather simple to me.
I want to prompt the user for input, but have them fill in a sort of template. Let's use a simple DD-MM-YYYY date as an example.
[█ - - ]
█ is where the user writes.
As they write, the [ and - stay where they are, with the cursor jumping past them, and hitting enter submits.
I'm not expecting anyone to write all of this for me, but cin and cout seem to be too crude a tools to do this, and so I'm wondering where I should even start, if not there.
Is there something that already does this, or at least something that gives me more control of the cursor to allow me to write it myself?
I do not want to be drawing a full-on TUI with windows and boarders and colors, so ncurses would just get in the way. I just want a single-line text field that returns the input.
EDIT: The most promising non-ncruses alternative for a helpful library seems to be Terminal.
Generally what you want is a text-based GUI library, such as ncurses. Doing console work is platform-specific, and every system has its own console API to do this. If you want to implement this yourself, you would have to examine what options does your target operating system give you in terms of console API, and build a custom solution based on that.

How does GDB pretty printer know the output format the user is requesting?

I have a few complex classes generated by a third party domain-specific tool. The classes are complex because the tool tries to be generic as much as possible, so that I was asked to design a GDB pretty printer python script to improve the debugging experience.
I designed it by "to_string" APIs which can print the information with organized rich text (e.g. colors), so far everything works fine.
However, I don't know how to get the output format user requests, no matter that user uses "p" or "p/x" will all output the same string because my script does not know user wants hex rather than decimal.
I tried googling but didn't figure out an elegant approach. I indeed have a few workarounds but they all change the usages (for example, implement two printers to be switched), please give me some suggestions, thank you.
Just realized there had been a feature request to GDB already.
Bug 17291 - IWBN if the print format was available to pretty-printers.

Python: Grab text printed to console

I'm using a complicated python module called CAMFR. In one function, it calculates a value that I want to use (to plot or otherwise), but unfortunately the module prints this value to the python console but doesn't return it as a variable!
(I have poked through the source code to see if I can recompile the module to return the values, but this looks excessively difficult at my programming level, considering it's written in C++ and uses Boost etc. I just don't get it unfortunately.)
SO, option number two is to grab the text printed to the console and parse out the value I need.
How can I intercept or otherwise acquire this function's console output text in Python (2.7)? (I will RegEx it afterwards.)
Thanks!
Here is an example of the text printed to the Python console:
<<a lot of other output, and then at the end of the function:>>
...
# 1.05554 4.65843e-05 5.54592 0.0903205 1
# 1.05554 2.87907e-05 3.42757 0.0903205 1
# 1.05554 2.87907e-05 3.42757 0.0903205 1
Done pass 1: lambda 1.05554, gain 3.42757
I ultimately want to grab the Lambda=1.05544 & Gain=3.42757 values, for example, and shove them into variables. Grabbing the entire console output of this one function would allow me to do that via a subsequent RegEx search, so I'm looking for a way to do that.
I apologize if there is another thread with the answer I need, I could not figure out google search terms that got me what I needed. Thanks for your patience & generous help!

Interesting Console Program for C++ beginners

I’m teaching an entry-level C++ programming class. We only use iostream in the class (No GUI). It seems like students are not so excited to printout strings and numbers to their console. (Most students even never used the console before.) It is hard to motivate or convey the excitement of programming by showing strings in their console.
What would be a good and exciting console program that can be written by C++ beginners? I’m looking for something doable with basic C++ skill + a bit challenging + very exciting, which can motivate students to learn programming languages.
Any comments will be appreciated.
When I taught an undergrad intro course, we did the Game of Fifteen in straight C as the third homework project. It's pretty well scoped, and it's a game, so there's some inherent motivation there.
Back when I taught, I made an early project be an ATM machine.
Text-only interface, with basic operations like withdraw, deposit, query balance, transfer between accounts, etc.
It was something that everyone was already familiar with, it didn't take huge amounts of programming time, but it did help students feel like it was a practical and realistic program.
Other similar ideas would be a cash-register (handle refunds, coupons, items priced by the pound, sales-tax, store specials, etc, etc), or a cell-phone billing program (separate daytime, night, and weekend minutes, bill text messages, picture messages separately, etc).
How about a system that generates a set of poker hands from a deck? While clearly defined, the intricacies of ensuring no duplicate cards etc, make it a good entry level challenge.
As an extension, you could have the system take an input as to whether you want to bet or fold, and effectively play a poker game.
Finally, a good design would allow them to switch the console for a gui front-end later on (e.g. intermediate class).
I always enjoyed problems where there's a real world purpose for doing it. Something like calculating a mathematical equation, or a range of prime numbers. A lot of stuff on ProjectEuler would be good, I would think. Not everybody likes math (but then again, it's kind of a necessary thing for computer science!).
Instead of just printing to the screen you could make ascii animations.
Introduce your students to pipes and filters. Create a useful utility that takes data from stdin and directs its output to stdout. Create another utility that does something else using that same protocol. Create a third utility. Demonstrate how robustly the utilities can work together.
For example, create a clone of the GNU head and tee utilities, and perhaps add a new utility called cap which capitalizes letters. Then demonstrate how you can get the first 3 lines of a text file capitalized and tee'd to a file and stdout. Next, demonstrate how you use the same utilities, without changing a single line of code, to take the first 5 lines of a file and output to the screen the capitalized letters and to a file the original letters.
When I took C++ we had to replicate a Theseus and the Minotaur game. It lends well to outputting multiple lines to the console to form something "graphical" and it's easily based on a set of implemented rules.
I've had to program a Tower of Hanoi game in the console before, I found that quite fun. It requires use of basic data structures, user input, checking for game end conditions so it would be good for a beginner I believe.
New programming students usually find graphical programs to be the most exciting.
It doesn't have to be anything really advanced, just being able to manipulate pixels and stuff should be enough to keep them interested. Making a simple graphic class around SDL should be ok. Maybe something like this:
int main()
{
GraphicWindow graphic;
graphic.setPixel(10,20,GraphicWindow::Red);
graphic.idle();
}
Then you give out assignments like "implement a drawRect function" etc.
Perhaps a text-only version of the Lunar Lander game. You could do full ASCII art and animations (with ncurses, perhaps) as an advanced exercise, but even in a pure text form it can be interesting.
I recall playing the version that ran on the HP 67 calculator, and it was entertaining with only a seven segment display to work with.
I vaguely recall a version that probably ran on an ALTAIR 8800 written in MITS/Microsoft BASIC that used the leading part of the line to show height above ground as ASCII art, with your prompt for the next tick's burn at the right.
Another traditional choice would be to implement Hunt the Wumpus, or for the ambitious, Battleship.
One of my first programming class had a long homework about implementing a (reduced) Monopoly game.
You can use chained lists for the board.
You can use Inheritance for board tiles.
You need some logic to process players turns.
It was probably the first project I've done in CS that I could talk about to my non-tech friends and generate some interest.

I want to show off my C++ projects through a website

The problem is that, well, it's C++. The way I've created them makes it such that they've always been run via a terminal/console window and wait for user input or else simply take a sample input and run with that. The output has also always been to the terminal screen or sometimes to a file. I'm not quite sure how I could take all of that and integrate it with a website while leaving the source code as it is, if that's at all possible. I guess what I'm trying to aim for is to have whatever website I use behave like a terminal window that will accept user input and then send it off to run the C++ program in question and return with the output (whatever it may be), all with minimal modification to the source code. Either that or else set up a more automated kind of page where a user can just click 'Go' and the program will run using a sample input.
When it comes to web I consider myself intermediate with HTML, CSS, PHP & MySQL, and a beginner with Javascript, so if this can be accomplished using those languages, that would be fantastic. If not, don't be afraid to show me something new though.
The easiest interaction model to bring to the web is an application that takes its input up front and produces its output on stdout. In this situation, as the unknown poster mentioned, you could use CGI. But due to the nature of CGI, this will only work (in the simplest sense) if all the information is collected from the user in one page, sent to the application and the results returned in one page. This is because each invocation of a page using CGI spawns a new indepdent process to serve the request. (There are other more efficient solutions now, such as FastCGI which keeps a pool of processes around.) If your application is interactive, in that it collects some information, presents some results, prints some options, collects some more user input, then produces more results, it will need to be adapted.
Here is about the simplest possible CGI program in C++:
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Content-type: text/plain\n" << std::endl;
std::cout << "Hello, CGI World!" << std::endl;
}
All it does is return the content type followed by a blank line, then the actual content with the usual boring greeting.
To accept user input, you would write a form in HTML, and the POST target would be your application. It will be passed a string containing the parameters of the request, in the usual HTTP style:
foo.cgi?QTY=123&N=41&DESC=Simple+Junk
You would then need to parse the query string (which is passed to the program via the QUERY_STRING environment variable) to gather the input fields from the form to pass to your application. Beware, as parsing parameter strings is the source of a great number of security exploits. It would definitely be worthwhile finding a CGI library for C++ (a Google search reveals many) that does the parsing for you. The query data can be obtained with:
const char* data = getenv("QUERY_STRING");
So at a minimum, you would need to change your application to accept its input from a query string of name=value pairs. You don't even need to generate HTML if you don't want to; simply return the content type as text/plain to begin with. Then you can improve it later with HTML (and change the content type accordingly).
There are other more sophisticated solutions, including entire web frameworks such as Wt. But that would involve considerable changes to your apps, which you said you wished to avoid.
Almost off-topic, but you might want to take a look at Wt.
have you considered using cgi ... its 19th century technology which lets webserver execute programs written in C/C++ to run and generate output
I do not know much about it ... but I used it for some school projects
Show it all off with Screencasts. I use Camtasia Studio, but there are a ton of them out there: http://en.wikipedia.org/wiki/Screencast
Camtasia will even generate all of the HTML and Flash you need to upload to your web server. Buy a nice USB microphone, and write a script of what you're going to say and show.
What is the purpose of showing off your projects? Do you wish to impress your friends or employers?
It doesn't seem feasible to emulate or port your C++ console apps through a web interface.
I suppose you could write a bridge between a server side script and your C++ binary which passes the user input through to your app, then returns the result through the web interface. Bear in mind this would be a huge task for you to undertake.
Ruby have a compiler on their website which demonstrates this can be done.
However no one on the web would expect to run your C++ apps in a web browser. Also I think that anyone who is interested in running a C++ app would be totally comfortable with downloading a C++ binary that you made and running it (apart from the security risk) but when you think about it we download apps and run them all the time, whilst trusting the source.
I have a portfolio website which I created for the purpose of letting employers see my work. Take a look, it will give you an idea of another way you can do things.
Basically I provide the binaries for download, videos, screenshots and links. Things that the user can use to see my work quickly if they don't have time (or an appropriate computer) to run my projects on.
Good luck
I have no experience with this (other than hearing a guy on BART talk about implementing his server-side code all in C), but you might consider taking a look at SWIG (http://www.swig.org/). It allows you to wrap C++ so that you can access C++ code when using languages such as PHP.