How to format a float number in Jason to show only two decimals? - artificial-intelligence

How to format a number as a currency with two decimals in Jason?
The code bellow illustrates the case:
products([["Banana",1], ["Apple",2], ["Pinapple",2.5]]).
margin(2).
!printPrices.
+!printPrices: products(List) & margin(Z)<-
.length(List,LLenght);
-+listSize(0);
while(listSize(Sz) & Sz < LLenght)
{
.random(Y);
.nth(Sz,List,Item);
.nth(0,Item,Name);
.nth(1,Item,Price);
.print("Product(",Sz,"): ",Name," Price $",Y*Z+Price);
-+listSize(Sz+1);
}.
The output is, I'd like to make the output more readable. Notice that float point numbers have many algharisms.:
[sampleagent] Product(0): Banana Price $1.3689469979841409
[sampleagent] Product(1): Apple Price $2.0475157980624523
[sampleagent] Product(2): Pinapple Price $3.4849443740416803

In fact there is no default internal action in Jason to format it as you want. Howeven, you can create your own Internal Action doing like this:
import jason.asSemantics.*;
import jason.asSyntax.*;
public class formatCurrency extends DefaultInternalAction {
private static final long serialVersionUID = 1L;
#Override
public Object execute(TransitionSystem ts, Unifier un, Term[] args) throws Exception {
StringTerm result = new StringTermImpl(String.format("%.2f", Float.valueOf(args[0].toString())));
un.unifies(result, args[1]);
return true;
}
}
In your agent, you can call this action by:
package_name.formatCurrency(10.5555,Price);

Related

Hashmap in testNG dataprivider to reduce arguments passing to test method

I've been writing Test scripts using TestNG's DataProvider feature. Till now I was happy with the way I was doing it as the number of parameters I was passing was less than 10, but some of the new pages I am testing have more than 30-35 parameters, adding these parameters to the Test Method makes it look really ugly
Its a good way of dynamically passing parameters, but then using them is difficult as you have to be really careful with the indexes and prone to errors if this has to be done for a lot of methods.
I tried passing the test data as a ArrayList>, where the HashMap is the Column Name-Value pair but TestNG wont accept this as HashMap cant be cast as Object[]. The reason I thought of using HashMap is because you can query a key and get its value and the key is known to me. I could have written a common method to get the value and assign it to the variable representing the names of the fields on the page.
The Data Source (XLS) only stores the test data that is entered on the page, so its purely data-driven and not keyword based. All the pages I am testing are data entry pages.
What is the best way to have some kind of identity on the test data and also get TestNG to accept it.
As an alternative I created a map while taking data from Excel and passing to data provider at the same time I created a hashmap and stored it globally to access in my test method but this way won't remove passing arguments to my test method
Any help in this regards is really appreciated.
Thanks
Ketan
I tried passing the test data as a ArrayList>, where the HashMap is the Column Name-Value pair but TestNG wont accept this as HashMap cant be cast as Object[].
TestNG can very well work with a data driven method that uses a Map as a parameter which is fed by a data provider. The below sample should clarify that.
In this example I have an excel spreadsheet, in which there's a sheet with its name as "53799150" and whose data looks like below
+------------+------------+-------------+-----------------+
| TestcaseId | RollNumber | StudentName | StudentLocation |
+------------+------------+-------------+-----------------+
| 1 | S1001 | Po | Bengaluru |
| 2 | S1002 | Oogway | Chennai |
| 3 | S1003 | Shifu | Delhi |
| 4 | S1004 | TaiLung | Kolkata |
+------------+------------+-------------+-----------------+
The below sample works with the above shown data as a map:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class MapPoweredDataProviderSample {
private static final String FILE = "src/test/resources/53799150.xlsx";
private static final DataFormatter dataFormatter = new DataFormatter();
private static final String SHEET_NAME = "53799150";
#Test(dataProvider = "dp")
public void testMethod(Map<String, String> data) {
System.err.println(data);
}
#DataProvider(name = "dp")
public Object[][] getData() throws IOException, InvalidFormatException {
Workbook workbook = WorkbookFactory.create(new File(FILE));
Sheet sheet = workbook.getSheet(SHEET_NAME);
Iterable<Row> rows = sheet::rowIterator;
List<Map<String, String>> results = new ArrayList<>();
boolean header = true;
List<String> keys = null;
for (Row row : rows) {
List<String> values = getValuesInEachRow(row);
if (header) {
header = false;
keys = values;
continue;
}
results.add(transform(keys, values));
}
return asTwoDimensionalArray(results);
}
private static Object[][] asTwoDimensionalArray(List<Map<String, String>> interimResults) {
Object[][] results = new Object[interimResults.size()][1];
int index = 0;
for (Map<String, String> interimResult : interimResults) {
results[index++] = new Object[] {interimResult};
}
return results;
}
private static Map<String, String> transform(List<String> names, List<String> values) {
Map<String, String> results = new HashMap<>();
for (int i = 0; i < names.size(); i++) {
String key = names.get(i);
String value = values.get(i);
results.put(key, value);
}
return results;
}
private static List<String> getValuesInEachRow(Row row) {
List<String> data = new ArrayList<>();
Iterable<Cell> columns = row::cellIterator;
for (Cell column : columns) {
data.add(dataFormatter.formatCellValue(column));
}
return data;
}
}
Here's the output:
{TestcaseId=1, RollNumber=S1001, StudentName=Po, StudentLocation=Bengaluru}
{TestcaseId=2, RollNumber=S1002, StudentName=Oogway, StudentLocation=Chennai}
{TestcaseId=3, RollNumber=S1003, StudentName=Shifu, StudentLocation=Delhi}
{TestcaseId=4, RollNumber=S1004, StudentName=TaiLung, StudentLocation=Kolkata}
===============================================
Default Suite
Total tests run: 4, Passes: 4, Failures: 0, Skips: 0
===============================================

Populating a table from a file only last column is populated JavaFX [duplicate]

This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.

Can I print Individual elements of DataSteam<T> in Apache Flink without using inbuilt print() function

I am trying to Print the values of warnings that have been detected in Flink
// Generate temperature warnings for each matched warning pattern
DataStream<TemperatureEvent> warnings = tempPatternStream.select(
(Map<String, MonitoringEvent> pattern) -> {
TemperatureEvent first = (TemperatureEvent) pattern.get("first");
return new TemperatureEvent(first.getRackID(), first.getTemperature()) ;
}
);
// Print the warning and alert events to stdout
warnings.print();
I am getting output as below(as per toString of eventSource function)
Rack id = 99 and temprature = 76.0
Can someone tell me, if there is any way I can print the values of DataStream without using print? An example would be, if I only want to print temperature, how can I access Individual elements in DataStream.
Thanks in Advance
I have figured out a way to access individual elements, Lets assume we have a DataStream
HeartRate<Integer,Integer>
It has 2 attributes
private Integer Patient_id ;
private Integer HR;
// Generating a Datasteam using custom function
DataStream<HREvent> hrEventDataStream = envrionment
.addSource(new HRGenerator()).assignTimestampsAndWatermarks(new IngestionTimeExtractor<>());
Assuming that you have Generated a Datasteam using custom function ,now we can print the values of Individual Elements of HeartRateEvent as below
hrEventDataStream.keyBy(new KeySelector<HREvent, Integer>() {
#Override
public Integer getKey(HREvent hrEvent) throws Exception {
return hrEvent.getPatient_id();
}
})
.window(TumblingEventTimeWindows.of(milliseconds(10)))
.apply(new WindowFunction<HREvent, Object, Integer, TimeWindow>() {
#Override
public void apply(Integer integer, TimeWindow timeWindow, Iterable<HREvent> iterable, Collector<Object> collector) throws Exception {
for(HREvent in : iterable){
System.out.println("Patient id = " + in.getPatient_id() + " Heart Rate = " + in.getHR());
}//for
}//apply
});
Hope it Helps !

The begin and end time of windows

What would be the way to show the begin and end time of windows? something like implement user-defined windows?
Would like to know the time that windows begin and evaluate such that the output is
quantity(WindowAll Sum), window_start_time, window_end_time
12, 1:13:21, 1:13:41
6, 1:13:41, 1:15:01
Found the answer. TimeWindow.class has getStart() and getEnd()
example usage:
public static class SumAllWindow implements AllWindowFunction<Tuple2<String,Integer>,
Tuple3<Integer, String, String>, TimeWindow> {
private static transient DateTimeFormatter timeFormatter =
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SS").withLocale(Locale.GERMAN).
withZone(DateTimeZone.forID("Europe/Berlin"));
#Override
public void apply (TimeWindow window, Iterable<Tuple2<String, Integer>> values,
Collector<Tuple3<Integer, String, String>> out) throws Exception {
DateTime startTs = new DateTime(window.getStart(), DateTimeZone.forID("Europe/Berlin"));
DateTime endTs = new DateTime(window.getEnd(), DateTimeZone.forID("Europe/Berlin"));
int sum = 0;
for (Tuple2<String, Integer> value : values) {
sum += value.f1;
}
out.collect(new Tuple3<>(sum, startTs.toString(timeFormatter), endTs.toString(timeFormatter)));
}
}
in main()
msgStream.timeWindowAll(Time.of(6, TimeUnit.SECONDS)).apply(new SumAllWindow()).print();

App-engine query

I am new to app-engine Datastore and to NoSQL world in common. I am developing a simple application where a user can declare his/her expenses everyday. Every user(Account) has its own declared expenses. The dash board contains a simple GWT Cell Tree which contains all the years in which the use declared expenses and when he/she clicks on a years, he gets all the months of the years then he clicks on the month and he gets all the days of the month and finally clicking on a day and he gets all the expenses declared in that day. It is something like
*2010
|_ jan
|_1
|_2
|_Food 12d
|_Dress 200d
|_Fun 150d
|_ ...
|_ feb
|_ ...
*2011
|_ jan
|_ feb
|_...
I save expenses entities in the data store for each user(Account) as the account the parent of all the expenses. my expense is as follow:
public class Expense implements Serializable, Comparable {
private String name;
private double price;
private Date date;
public Expense(String name, double price, Date date) {
this.name = name;
this.price = price;
this.date = date;
}
public Expense() {
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public boolean isPriceValid() {
return price > 0;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(double price) {
this.price = price;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
#Override
public int compareTo(Expense expense) {
if (name.equals(expense.getName())) {
if (date.equals(expense.getDate())) {
return new Double(price).compareTo(expense.getPrice());
}
return date.compareTo(expense.getDate());
}
return name.compareTo(expense.getName());
}
My QUESTION IS: How to query the expenses in the data store and return all different years relater to a specified Account and put them in a list or set or anything else where I can list them ? does I need to fetch all the expenses entities and iterate over them and get all the different years. doesn't sound reasonable. Any advice will be welcome and THANKS IN ADVANCE.
Several comments related to your post :
--> I wouldn't store a financial amount as a Double. Going that route will lead you to big problems with rounding errors. There are a lot of posts on this one. I would suggest you to store it as "DollarCent" and declare it as an integer. You simply multiply the amount by 100 when you store it and when displaying it you divide by 100.
--> Why do you declare your entity in the Datastore as implementing Serializable ? I would store without Serializable.
--> Related to the specific question on displaying the data by year, reading your question I see no other way than fetching the data. What I would do is ask GAE to order the data to avoid having to order it afterwards. Using Objectify, it would simply be q.filter(...).order(-date).order(amount).
Hope this helps !
Hugues

Resources