Reading multiple inputs from Dart Console - dart

I want to read different data from the console in a Dart server application, like:
forename : user inputs and enters
lastname : user inputs and enters
age : user inputs and enters
The following code works, but for 1 input item only:
var stream = new StringInputStream(stdin);
stream.onData = () {
voornaam = stream.readLine();
};
But I can't get it to work for multiple items.
Is there an easy way to do this in Dart ?
Thanks!

Since you're using a StringInputStream rather than just a standard InputStream, and because you're looking to read text. Unless there's a particular reason, I would recommend using the onLine handler over the onData. On data will basically try to 'stream' the information in that it's called immediately not on a new line itself. Try something like the following (note, not complete code, missing proper error handling etc.)
#import('dart:io');
main() {
var stream = new StringInputStream(stdin);
stream.onLine = () {
var str = stream.readLine().trim();
print(str.toUpperCase());
if(str == 'EXIT') exit(0);
};
}
One other note to point out, if you ever are data-streaming and using the onData handler, it is recommended that you then use the read method, as opposed to the readLine method to retrieve your content, again due to the nature of onData not waiting for a full line of text to be received before being called.

import 'dart:io';
void main() {
print('-----welcome-----');
print('what is your firstname');
var fname = stdin.readLineSync();
print('what is your lastname');
var lname = stdin.readLineSync();
print('what is your age');
int age = int.parse(stdin.readLineSync());
int left = 100 - age;
print('your name is $fname $lname and you are $age years');
}

Related

Create a new stream from a stream in Dart

I suspect that my understanding of Streams in Dart might have a few holes in it...
I have a situation in which I'd like a Dart app to respond to intermittent input (which immediately suggests the use of Streamss -- or Futures, maybe). I can implement the behavior I want with listener functions but I was wondering how to do this in a better, more Dartesque way.
As a simple example, the following (working) program listens to keyboard input from the user and adds a div element to the document containing what has been typed since the previous space, whenever the space bar is hit.
import 'dart:html';
main() {
listenForSpaces(showInput);
}
void listenForSpaces(void Function(String) listener) {
var input = List<String>();
document.onKeyDown.listen((keyboardEvent) {
var key = keyboardEvent.key;
if (key == " ") {
listener(input.join());
input.clear();
} else {
input.add(key.length > 1 ? "[$key]" : key);
}
});
}
void showInput(String message) {
document.body.children.add(DivElement()..text = message);
}
What I'd like to be able to do is to create a new Stream from the Stream that I'm listening to (in the example above, to create a new Stream from onKeyDown). In other words, I might set the program above out as:
var myStream = ...
myStream.listen(showInput);
I suspect that there is a way to create a Stream and then, at different times and places, insert elements to it or call for it to emit a value: it feels as though I am missing something simple. In any case, any help or direction to documentation would be appreciated.
Creating a new stream from an existing stream is fairly easy with an async* function.
For a normal stream, I would just do:
Stream<String> listenForSpaces() async* {
var input = <String>[];
await for (var keyboardEvent in document.onKeyDown) {
var key = keyboardEvent.key;
if (key == " ") {
yield input.join();
input.clear();
} else {
input.add(key.length > 1 ? "[$key]" : key);
}
}
}
The async* function will propagate pauses through to the underlying stream, and it may potentially pause the source during the yield.
That may or may not be what you want, since pausing a DOM event stream can cause you to miss events. For a DOM stream, I'd probably prefer to go with the StreamController based solution above.
There are several methods and there is a whole package rxdart to allow all kinds of things.
Only the final consumer should use listen and only if you need to explicitly want to unsubscribe, otherwise use forEach
If you want to manipulate events like in your example, use map.
I wasn't originally planning to answer my own question but I have since found a very simple answer to this question in the dartlang creating streams article; in case it's helpful to others:
Specifically, if we'd like to create a stream that we can insert elements into at arbitrary times and places in the code, we can do so via the StreamController class. Instances of this class have an add method; we can simply use the instance's stream property as our stream.
As an example, the code in my question could be rewritten as:
import 'dart:html';
import 'dart:async';
main() async {
// The desired implementation stated in the question:
var myStream = listenForSpaces();
myStream.listen(showInput);
}
Stream<String> listenForSpaces() {
// Use the StreamController class.
var controller = StreamController<String>();
var input = List<String>();
document.onKeyDown.listen((keyboardEvent) {
var key = keyboardEvent.key;
if (key == " ") {
// Add items to the controller's stream.
controller.add(input.join());
input.clear();
} else {
input.add(key.length > 1 ? "[$key]" : key);
}
});
// Listen to the controller's stream.
return controller.stream;
}
void showInput(String message) {
document.body.children.add(DivElement()..text = message);
}
(As mentioned in the article, we need to be careful if we want to set up a stream from scratch like this because there is nothing to stop us from inserting items to streams that don't have associated, active subscribers; inserted items would in that case be buffered, which could result in a memory leak.)

How to create HL7 message ORU_R01 type using HAPI 2.4

I am newbie to HL7. I am trying to construct HL7 message ORU_R01 type using HAPI 2.4. I got incorrect message format when I add patient details in the below code; otherwise the format is ok. How to fix this issue? is there any example to construct HL7 ORU message with PID,ORC,OBR and OBX?
Output without patient
MSH|^~\&|IM|ABC-ClinPath|ABC-vet|ABC-VetMed|20180412124041||ORU^R01
Output with patient (If I comment the patient details in the code)
PID||TEST|||^TESTlinPath|ABC-vet|ABC-VetMed|20180412124041||ORU^R01
import ca.uhn.hl7v2.model.v24.message.ORM_O01;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.model.v24.segment.MSH;
import ca.uhn.hl7v2.model.v24.group.ORM_O01_PATIENT;
public class CreateORUMessage {
private String sendingApplication = "IM";
private String sendingFacility = "ABC-ClinPath";
private String receivingApplication = "ABC-vet";
private String receivingFacility = "ABC-VetMed";
private void createHL7Message(){
try{
ORM_O01 order = new ORM_O01();
//ORU_R01 oru = new ORU_R01();
// Populate the MSH Segment
// Example - MSH|^~\&|HISA_8592|HISF_2603|||200706081131||ADT^A04|HL7O.1.11379|D|2.1
MSH mshSegment = order.getMSH();
mshSegment.getFieldSeparator().setValue("|");
mshSegment.getEncodingCharacters().setValue("^~\\&");
mshSegment.getSendingApplication().getNamespaceID().setValue(sendingApplication);
mshSegment.getSendingFacility().getNamespaceID().setValue(sendingFacility);
mshSegment.getReceivingApplication().getNamespaceID().setValue(receivingApplication);
mshSegment.getReceivingFacility().getNamespaceID().setValue(receivingFacility);
mshSegment.getDateTimeOfMessage().getTimeOfAnEvent().setValue("20180412124041");
mshSegment.getMessageType().getMessageType().setValue("ORU");
mshSegment.getMessageType().getTriggerEvent().setValue("R01");
//PID - patient details
ORM_O01_PATIENT orm_pid = order.getPATIENT();
orm_pid.getPID().getPid5_PatientName(0).getGivenName().setValue("TEST");
orm_pid.getPID().getPid2_PatientID().getCx1_ID().setValue("TEST");
// Now, let's encode the message and look at the output
HapiContext context = new DefaultHapiContext();
Parser parser = context.getPipeParser();
String encodedMessage = parser.encode(order);
System.out.println("Printing ER7 Encoded Message:");
System.out.println(encodedMessage);
//String msg = order.encode();
//System.out.println(msg);
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String args[]){
new CreateORUMessage().createHL7Message();
}
}
I tried other way too, but it's not worked :(
String msg = order.encode();
System.out.println(msg);
Your problem most likely is, that the segment separator character in HL7 is CR, which just resets the cursor to the start of the line and the next line overwrites the previous one. This only affects writing the message to the console. Writing to file or sending over TCP should be fine without any further conversions.
I had the same problem in an application once, this is my solution below.
ORU_R01 outMessage = new ORU_R01();
outMessage.setParser(hapiContext.getPipeParser());
outMessage.initQuickstart("ORU", "R01", "T");
MSH mshSegment = outMessage.getMSH();
mshSegment.getMsh3_SendingApplication().getHd1_NamespaceID().setValue("MIG-TOOL");
/* some code removed */
PID pidSegment = outMessage.getRESPONSE().getPATIENT().getPID();
pidSegment.getPid3_PatientIDInternalID(0).parse(reportData.getPatientId());
/* some more code removed */
LOGGER.trace("Generated message contents:\n" + replaceNewlines(outMessage.encode()));
And the code for replaceNewLines() is quite simple
private static String replaceNewlines(String input) {
return input.replaceAll("\\r", "\n");
}

Unable to get a mapping value

I'm trying to implement a small contract to upload file hashes on the blockchain along with the file description and the sender address. I've programmed this small contract :
pragma solidity^0.4.17;
contract hashes {
mapping(uint => string) descriptions;
mapping(uint => address) senderAddresses;
function uploadHash(uint _hash, string _description) public {
require(bytes(descriptions[_hash]).length == 0);
descriptions[_hash] = _description;
senderAddresses[_hash] = msg.sender;
}
function getHash(uint _hash) public returns (address, string){
return (senderAddresses[_hash], descriptions[_hash]);
}
}
I think uploadHash works as expected since when I'm uploading the same hash twice I get a revert. However when I'm trying to use getHash, I don't get any return value. The results are the same when I'm calling from remix or directly from web3.
Thanks in advance !
I believe you're missing the view modifier
function getHash(uint _hash) public view returns (address, string)
Remix will not show the res next to the input boxes unless you use the view modifier.

Lucene does not index some words?

I use leucene.net for my site and it Index some of the words fine and correct but it doesn't index some words like "الله"!
I have see the indexed file with Luke and it shows that "الله"is not indexed.
I have used ArabicAnalyzer for indexing.
you can see my site at www.qoranic.com , if you search "مریم" it will be ok but if you search "الله" it shows nothing.
any idea is appreciated in forward.
The ArabicAnalyzer does some transformation to that input; it will transform the input الله to له. This is due to the usage of the ArabicStemFilter (and ArabicStemmer) which is documented with ...
Stemming is defined as:
Removal of attached definite article, conjunction, and prepositions.
Stemming of common suffixes.
This shouldn't be an issue since you should be parsing the user provided query through the same analyzer when searching, producing the same tokens.
Here's the sample code I used to see what terms an analyzer produced from a given input.
using System;
using Lucene.Net.Analysis.AR;
using Lucene.Net.Analysis.Tokenattributes;
using System.IO;
namespace ConsoleApplication {
public static class Program {
public static void Main() {
var luceneVersion = Lucene.Net.Util.Version.LUCENE_30;
var input = "الله";
var analyzer = new ArabicAnalyzer(luceneVersion);
var inputReader = new StringReader(input);
var stream = analyzer.TokenStream("fieldName", inputReader);
var termAttribute = stream.GetAttribute<ITermAttribute>();
while(stream.IncrementToken()) {
Console.WriteLine("Term: {0}", termAttribute.Term);
}
Console.WriteLine("Done.");
Console.ReadLine();
}
}
}
You can overcome this behavior (remove the stemming) by writing a custom Analyzer which uses the ArabicNormalizationFilter, just as ArabicAnalyzer does, but without the call to ArabicStemFilter.
public class CustomAnalyzer : Analyzer {
public override TokenStream TokenStream(String fieldName, TextReader reader) {
TokenStream result = new ArabicLetterTokenizer(reader);
result = new LowerCaseFilter(result);
result = new ArabicNormalizationFilter(result);
return result;
}
}

Pass a URL into a Dart app

I have a page with links. These links all end in the same way. For example www.site.com/fruit/apples, www.site.com/fruit/bananas, www.site.com/fruit/oranges, etc. I want all these links to call the same Dart app and have the app do some processing and then redirect you wherever you need to go (the bananas page vs. the oranges page). This way, I avoid having an actual HTML file for every single fruit. I can instead have a single landing template that gets populated with variable fruit data.
The part I'm hung up on is passing the url into the Dart app so it can do the handling. I understand main() cannot receive arguments, so what's another way?
You can use the route package to handle the URL's for you.
For example:
import 'package:route/client.dart';
final fruitUrl = new UrlPattern(r'/fruit/(\w+)');
main() {
var router = new Router()
..addHandler(fruitUrl, showFruit)
..listen();
}
void showFruit(String path) {
var fruit = fruitUrl.parse(req.path)[0];
// Display the page according to the fruit type
}
If you don't need to handle actual routes, and you just want to handle any query parameters passed of the form ?fruit=apple you don't have to use the routes package and can instead manually parse the URL:
Map params = {};
// If arguments were provided, decode them into params map
if(window.location.search.length > 1) {
// Break all arguments into form: fruit=apple
List<String> queryPairs = window.location.search.substring(1).split('&');
for(String queryPair in queryPairs) {
// Add arguments into params map: key=fruit, value=apple
List<String> queryPairList = queryPair.split('=');
params[queryPairList[0]] = queryPairList[1];
}
}
// Handle the proper action based on the fruit
switch(params['fruit']) {
case 'apple':
// ...
break;
// ...
case 'orange':
// ...
break;
}

Resources