Second argument replacing first scala - arrays

I am trying to define a function in scala ( ^ ), which takes 2 values and prints them like
2
x
Here is what I have so far...
class $ (val text2D: Array[Array[Char]])
{
def ^(that: $) =
{
" " ++ s"${this.text2D(0)(0)}" ++
"\n" ++ s"${that.text2D(0)(0)}"
}
def +(that: $) = this.text2D + "+" + that.text2D
override def toString = s"${this.text2D(0)(0)}"
}
object $ {
val array = Array.ofDim[Char](1,1)
def apply(x: String): $ = {
array (0)(0) = x.charAt(0)
new $ (array)
}
}
val x = $("x")
println(x)
val x2 = $("x") ^ $("2")
println(x2)
When I run this, I do not get the output I am expecting, instead I get
2
2
Why is it only taking the second element? Any help would be appreciated.

object creates a singleton, so the (mutable) array that you use is shared between calls to apply. You need to allocate that array inside the apply call.
def apply(x: String): $ = {
val array = Array.ofDim[Char](1,1)
array (0)(0) = x.charAt(0)
new $ (array)
}
Also, slightly unrelated, but I believe you have your arguments backward. To get the output you want, you need
" " ++ s"${that.text2D(0)(0)}" ++
"\n" ++ s"${this.text2D(0)(0)}"

I think what you need is something like this:
class $(val text2D: Array[String]) {
def ^(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// cross-pad arrays to have the same width
val padThisRight = " " * thatW
val padThatLeft = " " * thisW
val thisPaddedW = this.text2D.map(_ + padThisRight)
val thatPaddedW = that.text2D.map(padThatLeft + _)
// first lines comes from that!
new $(thatPaddedW ++ thisPaddedW)
}
}
def +(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisH = this.text2D.length
val thatH = that.text2D.length
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// pad arrays to have the same height
val emptyThis = " " * thisW
val emptyThat = " " * thatW
val thisPaddedH = if (thisH >= thatH) this.text2D else Array.fill(thatH - thisH)(emptyThis) ++ this.text2D
val thatPaddedH = if (thisH <= thatH) that.text2D else Array.fill(thisH - thatH)(emptyThat) ++ that.text2D
new $(thisPaddedH.zip(thatPaddedH).map(p => p._1 + p._2))
}
}
override def toString = text2D.mkString("\n")
}
object $ {
def apply(x: String): $ = {
new $(Array[String](x))
}
}
and then
val x2 = $("x") ^ $("2")
println(s"x2:\n$x2")
println("----------------------------")
val z = x2 + $(" + ") + y2
println(s"z:\n$z")
println("----------------------------")
val zz = x2 + $(" + ") + (y2 ^ $("3"))
println(s"zz:\n$zz")
println("----------------------------")
produces following output
x2:
2
x
----------------------------
z:
2 2
x + y
----------------------------
zz:
3
2 2
x + y
----------------------------
The main idea here is that operations on $ produce another instance of $ rather than String (I use String instead of Array[Char] as it seems much easier and has no obvious drawbacks). In such way you don't have to re-parse String splitting it by new lines and have to wonder how to handle cases when the string is not well-aligned. So now operators ^ and + is just an exercise in aligning two 2d-arrays to have either the same width or the same height and then joining them.

Related

Alway get an error "No attribute named 'name' is defined" if try to process multiple lines from csv data feed

In my test script I try to process 100 lines data from csv data feed via following statement:
private val scn = scenario("test_scn").feed(insertFeeder, 100).exec(httpReq)
But I always get an error:
[ERROR] HttpRequestAction - 'httpRequest-1' failed to execute: No attribute named 'name' is defined
Could you please help me to find out the root cause? thank you.
Here is the script:
private val insertFeeder = csv("test_data.csv").queue
private val csvHeader = GeneralUtil.readFirstLine(""test_data.csv"")
private val httpConf = http .baseURL("http://serviceURL") .disableFollowRedirect .disableWarmUp .shareConnections
private var httpReq = http("insert_request") .post("/insert")
for (i <- 0 to 99) {
val paramsInArray = csvHeader.split(",")
for (param <- paramsInArray) {
if (param.equalsIgnoreCase("name")) {
httpReq = httpReq.formParam(("name" + "[" + i +"]").el[String] , "${name}")
}
if (param.equalsIgnoreCase("url")) {
httpReq = httpReq.formParam(("url" + "[" + i +"]").el[String] , "${url}")
}
if (!param.equalsIgnoreCase("name") && !param.equalsIgnoreCase("url")) {
val firstArg = param + "[" + i + "]"
val secondArg = "${" + param + "}"
httpReq = httpReq.formParam(firstArg, secondArg)
}
}
}
private val scn = scenario("test_scn") .feed(insertFeeder, 100) .exec(httpReq)
setUp( scn.inject( constantUsersPerSec(1) during (1200 seconds) ).protocols(httpConf) ).assertions(global.failedRequests.count.lte(5))
And the data in test_data.csv is:
name,url,price,size,gender
image_1,http://image_1_url,100,xl,male
image_2,http://image_2_url,90,m,female
image_3,http://image_3_url,10,s,female
...
image_2000,http://image_2000_url,200,xl,male
By the way, if I process only 1 line, it works well.
Read the document again, and fixed the issue. If feed multiple records all at once, the attribute names will be suffixed from 1.
https://gatling.io/docs/current/session/feeder/#csv-feeders

Array of size n to array n x 2 using Java 8 stream

I am trying to figure out the most elegant way of converting a simple int array (e.g. {1, 2, 3}) to a simple String array (e.g. {"id", "1", "id", "2", "id", "3"}) of String pairs using Java 8 streams.
Traditionally the code looks like this: -
int[] input = {1, 2, 3};
String[] output = new String[input.length * 2];
int i = 0;
for (int val : input) {
output[i++] = "id";
output[i++] = String.valueOf(val);
}
But assuming this can be done in a 1-liner in Java 8.
String[] result = Arrays.stream(input)
.mapToObj(x -> new String[] { "id", "" + x })
.flatMap(Arrays::stream)
.toArray(String[]::new);
Or may be a bit more verbose (but worse since we are first joining, only to split immediately after)
String[] result = Arrays.stream(input)
.mapToObj(x -> "id" + "," + x)
.collect(Collectors.joining(","))
.split(",");
I can think of these two, but it's hardly more readable of what you already have in place with a simple for loop.
Can make it even less readable than Eugene's solution:
String[] output = IntStream.range(0, input.length * 2)
.mapToObj(x -> x % 2 == 0 ? "id" : input[x / 2 ] + "")
.toArray(String[]::new);
And another variation of this can be next:
String[] result = Arrays.stream( input )
.boxed()
.flatMap( x -> Stream.of( "id", Integer.toString( x ) ) )
.toArray( String[]::new );

AS2 Extract top 5 from array

Good evening everyone!
Anyone knows how to extract the top 5 numbers (the highest) from an array?
I have an XML with names, surnames and score and want to extract the top 5 to create a chart.
As for now, I am getting all the info in this way:
num = xmlData.childNodes.length;
for (var i = 0; i <= num - 1; i++)
{
names[i] = this.childNodes[i].childNodes[6].firstChild.nodeValue;
surnames[i] = this.childNodes[i].childNodes[5].firstChild.nodeValue;
points[i] = this.childNodes[i].childNodes[0].firstChild.nodeValue;
pointsint[i] = parseInt(speeds[i]);
trace(i + "." + pointsint[i] + " (" + names[i] + " " + surnames[i] + ")");
}
Thank you for any help!
Organize data as generic object entries and Array.sortOn(...) (http://help.adobe.com/en_US/as2/reference/flashlite/WS5b3ccc516d4fbf351e63e3d118ccf9c47f-7ea5.html). I didn't test it but I think the idea is clear:
var num = xmlData.childNodes.length;
var entries = [];
for (var i = 0; i <= num - 1; i++)
{
var anEntry = {};
var aNode = xmlData.childNodes[i];
anEntry['name'] = aNode.childNodes[6].firstChild.nodeValue;
anEntry['surname'] = aNode.childNodes[5].firstChild.nodeValue;
var aSpeed = aNode.childNodes[0].firstChild.nodeValue;
anEntry['speed'] = parseInt(aSpeed);
entries.push(anEntry);
trace(i + "." + anEntry['speed'] + " (" + anEntry['name'] + " " + anEntry['surname'] + ")");
}
entries.sortOn("speed", Array.DESCENDING | Array.NUMERIC);
// Now first five elements of entries Array is what you want.

OpenMDAO v0.13: performing an optimization when using multiple instances of a components initiated in a loop

I am setting up an optimization in OpenMDAO v0.13 using several components that are used many times. My assembly seems to be working just fine with the default driver, but when I run with an optimizer it does not solve. The optimizer simply runs with the inputs given and returns the answer using those inputs. I am not sure what the issue is, but I would appreciate any insights. I have included a simple code mimicking my structure that reproduces the error. I think the problem is in the connections, summer.fs does not update after initialization.
from openmdao.main.api import Assembly, Component
from openmdao.lib.datatypes.api import Float, Array, List
from openmdao.lib.drivers.api import DOEdriver, SLSQPdriver, COBYLAdriver, CaseIteratorDriver
from pyopt_driver.pyopt_driver import pyOptDriver
import numpy as np
class component1(Component):
x = Float(iotype='in')
y = Float(iotype='in')
term1 = Float(iotype='out')
a = Float(iotype='in', default_value=1)
def execute(self):
x = self.x
a = self.a
term1 = a*x**2
self.term1 = term1
print "In comp1", self.name, self.a, self.x, self.term1
def list_deriv_vars(self):
return ('x',), ('term1',)
def provideJ(self):
x = self.x
a = self.a
dterm1_dx = 2.*a*x
J = np.array([[dterm1_dx]])
print 'In comp1, J = %s' % J
return J
class component2(Component):
x = Float(iotype='in')
y = Float(iotype='in')
term1 = Float(iotype='in')
f = Float(iotype='out')
def execute(self):
y = self.y
x = self.x
term1 = self.term1
f = term1 + x + y**2
self.f = f
print "In comp2", self.name, self.x, self.y, self.term1, self.f
class summer(Component):
total = Float(iotype='out', desc='sum of all f values')
def __init__(self, size):
super(summer, self).__init__()
self.size = size
self.add('fs', Array(np.ones(size), iotype='in', desc='f values from all cases'))
def execute(self):
self.total = sum(self.fs)
print 'In summer, fs = %s and total = %s' % (self.fs, self.total)
class assembly(Assembly):
x = Float(iotype='in')
y = Float(iotype='in')
total = Float(iotype='out')
def __init__(self, size):
super(assembly, self).__init__()
self.size = size
self.add('a_vals', Array(np.zeros(size), iotype='in', dtype='float'))
self.add('fs', Array(np.zeros(size), iotype='out', dtype='float'))
print 'in init a_vals = %s' % self.a_vals
def configure(self):
# self.add('driver', SLSQPdriver())
self.add('driver', pyOptDriver())
self.driver.optimizer = 'SNOPT'
# self.driver.pyopt_diff = True
#create this first, so we can connect to it
self.add('summer', summer(size=len(self.a_vals)))
self.connect('summer.total', 'total')
print 'in configure a_vals = %s' % self.a_vals
# create instances of components
for i in range(0, self.size):
c1 = self.add('comp1_%d'%i, component1())
c1.missing_deriv_policy = 'assume_zero'
c2 = self.add('comp2_%d'%i, component2())
self.connect('a_vals[%d]' % i, 'comp1_%d.a' % i)
self.connect('x', ['comp1_%d.x'%i, 'comp2_%d.x'%i])
self.connect('y', ['comp1_%d.y'%i, 'comp2_%d.y'%i])
self.connect('comp1_%d.term1'%i, 'comp2_%d.term1'%i)
self.connect('comp2_%d.f'%i, 'summer.fs[%d]'%i)
self.driver.workflow.add(['comp1_%d'%i, 'comp2_%d'%i])
self.connect('summer.fs[:]', 'fs[:]')
self.driver.workflow.add(['summer'])
# set up main driver (optimizer)
self.driver.iprint = 1
self.driver.maxiter = 100
self.driver.accuracy = 1.0e-6
self.driver.add_parameter('x', low=-5., high=5.)
self.driver.add_parameter('y', low=-5., high=5.)
self.driver.add_objective('summer.total')
if __name__ == "__main__":
""" the result should be -1 at (x, y) = (-0.5, 0) """
import time
from openmdao.main.api import set_as_top
a_vals = np.array([1., 1., 1., 1.])
test = set_as_top(assembly(size=len(a_vals)))
test.a_vals = a_vals
print test.a_vals
test.x = 2.
test.y = 2.
tt = time.time()
test.run()
print "Elapsed time: ", time.time()-tt, "seconds"
print 'result = ', test.summer.total
print '(x, y) = (%s, %s)' % (test.x, test.y)
print test.fs
I played around with your model, and found that the following line caused problems:
#self.connect('summer.fs[:]', 'fs[:]')
When I commented it out, I got the optimization to move.
I am not sure what is happening there, but the graph transformations sometimes have some issues with component input nodes that are promoted as outputs on the assembly boundary. If you still want those values to be available on the assembly, you could try promoting the outputs from the comp2_n components instead.

How can I add '€' in extjs?

All is in the question, is there a way to display the € symbol in extjs?
I tried
var euroMoney = function(v) {
v = (Math.round((v - 0) * 100)) / 100;
v = (v == Math.floor(v)) ? v + ".00" : ((v * 10 == Math.floor(v * 10)) ? v + "0" : v);
v = String(v);
var ps = v.split('.'),
whole = ps[0],
sub = ps[1] ? ',' + ps[1] : ',00',
r = /(\d+)(\d{3})/;
while (r.test(whole)) {
whole = whole.replace(r, '$1' + '.' + '$2');
}
v = whole + sub;
return v + " €";
}
But for euroMoney(1) it returns me
1,00 €
This happens when your text editor saves it the wrong way. Make sure the encoding in your text editor is set to UTF-8 and you should be fine.

Resources