Jetpack Compose layout challenge - android-layout

I'm trying to layout the following in compose but I cannot seem to get the alignment / arrangements to work correctly. I have tried starting with Row() and also trying starting with Column but the results are the same - misaligned.
So I have the following properties:
1. constantA = "774"
2. operator = "+"
3. constantB = "62"
4. line = "-------"
5. answer = "826"
6. icon = "checkmark"
The alignment needs to be as follows:
774
+ 52
-----
826 ✓
Any help or pointers will be appreciated!

In case you wanna use a regular Icon:
#Preview
#Composable
fun OperationPreview() {
val constantA = "774"
val operator = "+"
val constantB = "62"
val line = "-------"
val answer = "826"
Row(verticalAlignment = Alignment.Bottom) {
Column(horizontalAlignment = Alignment.End) {
Text(text = constantA)
Text(text = "$operator $constantB")
Text(text = line)
Row() {
Text(text = answer)
}
}
Icon(
modifier = Modifier
.size(10.dp)
.padding(bottom = 5.dp),
imageVector = Icons.Default.Check,
contentDescription = null
)
}
}

#Composable
fun TextAlignLayout() {
val constantA = "774" + " "
val operator = "+" + " "
val constantB = "62" + " "
val line = "-------" + " "
val answer = "826"
val icon = "✓"
Column(
modifier = Modifier
.padding(24.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.End
) {
Text(constantA)
Text("$operator$constantB")
Text(line)
Text("$answer $icon")
}
}

Related

how to extract an integer range from a string

I have a string that contains different ranges and I need to find their value
var str = "some text x = 1..14, y = 2..4 some text"
I used the substringBefore() and substringAfter() methodes to get the x and y but I can't find a way to get the values because the numbers could be one or two digits or even negative numbers.
One approach is to use a regex, e.g.:
val str = "some text x = 1..14, y = 2..4 some text"
val match = Regex("x = (-?\\d+[.][.]-?\\d+).* y = (-?\\d+[.][.]-?\\d+)")
.find(str)
if (match != null)
println("x=${match.groupValues[1]}, y=${match.groupValues[2]}")
// prints: x=1..14, y=2..4
\\d matches a single digit, so \\d+ matches one or more digits; -? matches an optional minus sign; [.] matches a dot; and (…) marks a group that you can then retrieve from the groupValues property. (groupValues[0] is the whole match, so the individual values start from index 1.)
You could easily add extra parens to pull out each number separately, instead of whole ranges.
(You may or may not find this as readable or maintainable as string-manipulation approaches…)
Is this solution fit for you?
val str = "some text x = 1..14, y = 2..4 some text"
val result = str.replace(",", "").split(" ")
var x = ""; var y = ""
for (i in 0..result.count()-1) {
if (result[i] == "x") {
x = result[i+2]
} else if (result[i] == "y") {
y = result[i+2]
}
}
println(x)
println(y)
Using KotlinSpirit library
val rangeParser = object : Grammar<IntRange>() {
private var first: Int = -1
private var last: Int = -1
override val result: IntRange
get() = first..last
override fun defineRule(): Rule<*> {
return int {
first = it
} + ".." + int {
last = it
}
}
}.toRule().compile()
val str = "some text x = 1..14, y = 2..4 some text"
val ranges = rangeParser.findAll(str)
https://github.com/tiksem/KotlinSpirit

Single Speechmarks not added to numbers

I have the below Code which works, except for if there is a number in the text field so a single speech mark does not get added around say 1 but would be around one.
As an aside I don't want speechmarks on the first column (the ID value)
SEP = ", "
QUOTE = "\'"
NEWLINE = System.getProperty("line.separator")
KEYWORDS_LOWERCASE = com.intellij.database.util.DbSqlUtil.areKeywordsLowerCase(PROJECT)
KW_INSERT_INTO = KEYWORDS_LOWERCASE ? "insert into " : "INSERT INTO "
KW_VALUES = KEYWORDS_LOWERCASE ? ") values (" : ") VALUES ("
KW_NULL = KEYWORDS_LOWERCASE ? "null" : "NULL"
def record(columns, dataRow) {
OUT.append(KW_INSERT_INTO)
if (TABLE == null) OUT.append("MY_TABLE")
else OUT.append(TABLE.getParent().getName()).append(".").append(TABLE.getName())
OUT.append(" (")
columns.eachWithIndex { column, idx ->
OUT.append(column.name()).append(idx != columns.size() - 1 ? SEP : "")
}
OUT.append(KW_VALUES)
columns.eachWithIndex { column, idx ->
def value = dataRow.value(column)
def stringValue = value != null ? FORMATTER.format(dataRow, column) : KW_NULL
if (DIALECT.getDbms().isMysql())
stringValue = stringValue.replace("\\", "\\\\")
OUT.append(skipQuote ? "": QUOTE).append(stringValue.replace(QUOTE, QUOTE + QUOTE))
.append(skipQuote ? "": QUOTE).append(idx != columns.size() - 1 ? SEP : "")
}
OUT.append(");").append(NEWLINE)
}
ROWS.each { row -> record(COLUMNS, row) }
Not 100% sure what and why you are trying to achieve, but I would write down something like that in idiomatic groovy:
LinkedHashMap.metaClass.value = { delegate.get it } // mock value()
TABLE = [ parent:[ name:'OTHER_TABLE' ] ] // fake TABLE
KEYWORDS_LOWERCASE = true // false
KW_INSERT_INTO = 'INSERT INTO'
KW_VALUES = 'VALUES'
if( KEYWORDS_LOWERCASE ){
KW_INSERT_INTO = KW_INSERT_INTO.toLowerCase()
KW_VALUES = KW_VALUES.toLowerCase()
}
COLUMNS = [ 'a', 'nullllll', 'c', 'numberString' ]
String record(columns, dataRow) {
List values = columns.collect{
def v = dataRow.value it
switch( v ){
case Number:
case ~/\d+/: return v
case String: return "'$v'"
default: return 'null'
}
}
"$KW_INSERT_INTO ${TABLE?.parent?.name ?: 'MY_TABLE'} (${columns.join( ', ' )}) $KW_VALUES (${values.join( ', ' )});\n"
}
String res = record( COLUMNS, [ a:'aa', c:42, numberString:'84' ] )
assert res == "insert into OTHER_TABLE (a, nullllll, c, numberString) values ('aa', null, 42, 84);\n"
In switch statement the values are getting formatted.
You can try out yourself at https://groovyconsole.appspot.com/script/5151418931478528

Is there any way to get the output of Spark's Dataset.show() method as a string?

The Spark Dataset.show() method is useful for seeing the contents of a dataset, particularly for debugging (it prints out a nicely-formatted table). As far as I can tell, it only prints to the console, but it would be useful to be able to get this as a string. For example, it would be nice to be able to write it to a log, or see it as the result of an expression when debugging with, say, IntelliJ.
Is there any way to get the output of Dataset.show() as a string?
The corresponding method behind show isn't visible from outside the sql package. I've taken the corresponding method and changed it such that a dataframe can be passed as parameter (code taken from Dataset.scala) :
def showString(df:DataFrame,_numRows: Int = 20, truncate: Int = 20): String = {
val numRows = _numRows.max(0)
val takeResult = df.take(numRows + 1)
val hasMoreData = takeResult.length > numRows
val data = takeResult.take(numRows)
// For array values, replace Seq and Array with square brackets
// For cells that are beyond `truncate` characters, replace it with the
// first `truncate-3` and "..."
val rows: Seq[Seq[String]] = df.schema.fieldNames.toSeq +: data.map { row =>
row.toSeq.map { cell =>
val str = cell match {
case null => "null"
case binary: Array[Byte] => binary.map("%02X".format(_)).mkString("[", " ", "]")
case array: Array[_] => array.mkString("[", ", ", "]")
case seq: Seq[_] => seq.mkString("[", ", ", "]")
case _ => cell.toString
}
if (truncate > 0 && str.length > truncate) {
// do not show ellipses for strings shorter than 4 characters.
if (truncate < 4) str.substring(0, truncate)
else str.substring(0, truncate - 3) + "..."
} else {
str
}
}: Seq[String]
}
val sb = new StringBuilder
val numCols = df.schema.fieldNames.length
// Initialise the width of each column to a minimum value of '3'
val colWidths = Array.fill(numCols)(3)
// Compute the width of each column
for (row <- rows) {
for ((cell, i) <- row.zipWithIndex) {
colWidths(i) = math.max(colWidths(i), cell.length)
}
}
// Create SeparateLine
val sep: String = colWidths.map("-" * _).addString(sb, "+", "+", "+\n").toString()
// column names
rows.head.zipWithIndex.map { case (cell, i) =>
if (truncate > 0) {
StringUtils.leftPad(cell, colWidths(i))
} else {
StringUtils.rightPad(cell, colWidths(i))
}
}.addString(sb, "|", "|", "|\n")
sb.append(sep)
// data
rows.tail.map {
_.zipWithIndex.map { case (cell, i) =>
if (truncate > 0) {
StringUtils.leftPad(cell.toString, colWidths(i))
} else {
StringUtils.rightPad(cell.toString, colWidths(i))
}
}.addString(sb, "|", "|", "|\n")
}
sb.append(sep)
// For Data that has more than "numRows" records
if (hasMoreData) {
val rowsString = if (numRows == 1) "row" else "rows"
sb.append(s"only showing top $numRows $rowsString\n")
}
sb.toString()
}

Divide Swift String into groups of 3 symbols

I'm making a formatter for currency string, for example I have Int:
let a: Int = 10
let b: Int = 10000
let c: Int = 10000000
I want them to be formatted like:
let a1:String = "10"
let b1:String = "10 000"
let c1:String = "10 000 000"
So I need funtion (or extension) in Swift as elegant, as you can suggest =) You have a Int as input parameter and you should output it as a String with " "(space symbol) every 3 symbols from right to left.
this may help you :
func formatNumberString(number : String?) -> String?
{
//"10 000 000 M"
// 01234567890123 -> 2,6,10
if (number?.isEmpty == true || number?.length <= 2) {
return number
}
var i : Int = 0
var newNumber : String = ""
for character in (number?.characters)! {
if ((i == 2 || i == 6 || i == 10) && character != " ")
{
newNumber = newNumber + " "
}
i++
}
return newNumber
}
You should user NSNumberFormatter to format your number:
func numberToCurrency(number: Int) -> String {
let formatter: NSNumberFormatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
formatter.positiveSuffix = " M"
formatter.currencySymbol = ""
formatter.maximumFractionDigits = 0
formatter.currencyGroupingSeparator = " "
formatter.usesGroupingSeparator = true
return formatter.stringFromNumber(number)!
}
print(numberToCurrency(1000)) will print 1 000 M. If you don't want to show M character, just set formatter.positiveSuffix = ""
You can use this as extension and just call if input is string
let requiredN = "10000000".convertToFormat()
this is the extension for string
extension String
{
func convertToFormat() -> String
{
return (NSNumberFormatter.localizedStringFromNumber(Int(self)!, numberStyle: NSNumberFormatterStyle.DecimalStyle) as String).stringByReplacingOccurrencesOfString(",", withString: " ")
}
}
If input value is Int call
let requiredN = 10000000.convertToFormat()
and extension for Int
extension Int
{
func convertToFormat() -> String
{
return (NSNumberFormatter.localizedStringFromNumber(self, numberStyle: NSNumberFormatterStyle.DecimalStyle) as String).stringByReplacingOccurrencesOfString(",", withString: " ")
}
}

rule identifier failed predicate

recently, i tried to do some pig script with groovy, here is my code
def appID = ['pub000000', 'pub000004', 'pub000001', 'pub000004'] as Object[]
before :appInfo = new Object[4]
now: **def appInfo = ['info1','info2','info3','info4']**
for (int i = 0; i < appInfo.size(); i++) {
//Load all the related appInfo tables
pigServer.registerQuery("${appInfo[i]} = LOAD'hbase://Information.${appID[i]}' " +
"USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('meta:number1 " +
"meta:number2') " +
"AS (number1:chararray, number2:chararray);")
}
pigServer.registerQuery("totalAppinfo = UNION ${appInfo[0]},${appInfo[1]},${appInfo[2]},${appInfo[3]};")
I worked it out finally, just to give the array the value.
Complete guess (never used piglatin), but does this work?
def appID = ['pub000000', 'pub000004', 'pub000001', 'pub000004']
appID.each { id ->
pigServer.registerQuery( "${id} = LOAD'hbase://Information.${id}' " +
"USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('meta:number1 " +
"meta:number2') " +
"AS (number1:chararray, number2:chararray);")
}
pigServer.registerQuery("totalAppinfo = UNION ${appId.join(',')};")
Edit after update to question:
def appID = ['pub000000', 'pub000004', 'pub000001', 'pub000004']
def appInfo = ['info1','info2','info3','info4']
[appInfo,appID].transpose().each { info, id ->
pigServer.registerQuery( "${info} = LOAD'hbase://Information.${id}' " +
"USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('meta:number1 " +
"meta:number2') " +
"AS (number1:chararray, number2:chararray);")
}
pigServer.registerQuery("totalAppinfo = UNION ${appInfo.join(',')};")

Resources