I’ve the following code which needs to get int value and add it to a string with string suffix. E.g.
At start I'm getting this
"fds data "
After the if statement it should like this
"fds data 10 M"
This is the code:
ltrCfg := "fds data "
if len(cfg.ltrSharedDicts) > 0 {
ltrCfg += strconv.Itoa(cfg.ltrSharedDicts["c_data"])
ltrCfg += "M"
} else {
ltrCfg += "10M"
}
out = append(out, ltrCfg)
ltrCert := “fds data "
if len(cfg.ltrSharedDicts) > 0 {
ltrCert += strconv.Itoa(cfg.ltrSharedDicts["d_data"])
ltrCert += "M"
} else {
ltrCert += “20M"
}
out = append(out, ltrCert)
The code is working but I wonder for the first fork of the if statement
if len(cfg.ltrSharedDicts) > 0 {
ltrCfg += strconv.Itoa(cfg.ltrSharedDicts["c_data"])
ltrCfg += "M"
Is there a better way to achieve it?
For readability, I would write:
cd, ok := cfg.ltrSharedDicts["c_data"]
if !ok {
cd = 10
}
out = append(out, fmt.Sprintf("fds data %dM", cd))
Related
I m trying to take an input from the user through my console in golang by using fmt.Scanln(). It is working fine under normal circumstances. However, whenever I take input in a loop, the inputs are correct in the first iteration but during the next iterations of a loop, an extra smiley is added in the front of the received string. I don't know what the problem is. Will be very thankful if anyone proposes some solution.
func (a *Block) fillBlock() {
fmt.Println("Block Details:")
fmt.Print("Enter Block Name: ")
fmt.Scanln(&a.Data)
for i := 0; i < Students; i++ {
fmt.Print(i, "Enter Student Roll# ")
fmt.Scanln(&a.Grades[i].Rollno)
fmt.Print(i, "Enter Student Grade# ")
fmt.Scanln(&a.Grades[i].Grade)
}
fmt.Println("\nInput Data:")
fmt.Println("Data: ",a.Data)
// Iterating over each student
for i := 0; i < Students && (a.Grades[i].Rollno != "" && a.Grades[i].Grade != ""); i++ {
fmt.Println("Rollno: " + string(i) + a.Grades[i].Rollno)
fmt.Println("Grade: " + string(i) + a.Grades[i].Grade)
}
}
This is wrong:
fmt.Println("Rollno: " + string(i) + a.Grades[i].Rollno)
Instead, use
fmt.Println("Rollno: " + strconv.Itoa(i) + a.Grades[i].Rollno)
Or, better:
fmt.Printf("Rollno: %d %s\n",i a.Grades[i].Rollno)
I'm trying to sort a list of jars by their filenames:
def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar']
jars = jars.sort().reverse()
println jars
The result is:
[app-5.2.0.jar, app-5.2.0-9.jar, app-5.2.0-10.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]
However, I'm more interested in the natural (and probably more intuitive) sorting to receive this sorted list:
[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]
Is there a way to achieve this?
this is my current algorithm for sorting but it's too verbose in my opinion. However, it really does what I'm looking for. Each part of the version (major, minor, maintenance, build) is evaluated independently:
jars = jars.sort { a, b ->
File fileA = new File(a)
File fileB = new File(b)
def partsA = fileA.name.findAll(/\d+/)
def partsB = fileB.name.findAll(/\d+/)
if (partsA[0] == null) partsA[0] = "0"
if (partsB[0] == null) partsB[0] = "0"
if (partsA[0].toInteger() < partsB[0].toInteger()) {
println "${partsA[0]} < ${partsB[0]}"
return -1
} else if (partsA[0].toInteger() > partsB[0].toInteger()) {
println "${partsA[0]} > ${partsB[0]}"
return 1
} else {
if (partsA[1] == null) partsA[1] = "0"
if (partsB[1] == null) partsB[1] = "0"
if (partsA[1].toInteger() < partsB[1].toInteger()) {
println "${partsA[1]} < ${partsB[1]}"
return -1
} else if (partsA[1].toInteger() > partsB[1].toInteger()) {
println "${partsA[1]} > ${partsB[1]}"
return 1
} else {
if (partsA[2] == null) partsA[2] = "0"
if (partsB[2] == null) partsB[2] = "0"
if (partsA[2].toInteger() < partsB[2].toInteger()) {
println "${partsA[2]} < ${partsB[2]}"
return -1
} else if (partsA[2].toInteger() > partsB[2].toInteger()) {
println "${partsA[2]} > ${partsB[2]}"
return 1
} else {
if (partsA[3] == null) partsA[3] = "0"
if (partsB[3] == null) partsB[3] = "0"
if (partsA[3].toInteger() < partsB[3].toInteger()) {
println "${partsA[3]} < ${partsB[3]}"
return -1
} else if (partsA[3].toInteger() > partsB[3].toInteger()) {
println "${partsA[3]} > ${partsB[3]}"
return 1
} else {
println "${partsA[3]} = ${partsB[3]}"
return 0
}
}
}
}
}
Had to try this:
def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar', 'app-1.0.jar', 'app-0.10.jar']
jars = jars.sort{ -it.findAll( /\d+/ ).join().toInteger() }
println jars
Gets:
[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar, app-1.0.jar, app-0.10.jar]
Or more thorough version that handles large patch versions:
def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar', 'app-5.1.1-172.jar']
jars.sort{ a, b ->
def aList = a.findAll(/\d+/)
def bList = b.findAll(/\d+/)
for ( int i = 0 ; i < aList.size() ; i++ ) {
def aVal = aList[i] ? aList[i].toInteger() : 0
def bVal = bList[i] ? bList[i].toInteger() : 0
if ( aVal <=> bVal ) { // only return if non-zero i.e. not equal
return aVal <=> bVal
}
}
bList.size() > aList.size() ? -1 : 0 // all facets match up to now, if b has additional parts it must be later version
}
println jars.reverse()
Gets:
[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1-172.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]
How about something like this:
def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar', 'app-5.1.1-172.jar']
// it is probably sufficient to just choose a "high enough" number
// (e.g. 10) instead of resolving max digits.
def maxDigits = jars*.findAll(/\d+/).flatten()*.size().max()
// sort the strings consisting of left-padded version numbers
// e.g. sorting string for 'app-5.1.1-172.jar' is ' 5 1 1172'
jars.sort{ it.findAll(/\d+/)*.padLeft(maxDigits).join() }
println 'max digits: ' + maxDigits
println jars.reverse()
Output:
max digits: 3
[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1-172.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]
I have installed kannel from the rpm package kannel-sw-1.4.3.3-6.rh5u3. Have done a simple tests like sent one by one five messages("1", "2", "3", "4" and "5") to smsbox over http get for handling throttling error. From SMSC side throughput was 2 SMS per minute. I expected to get sms in following order:
"1"
"2"
"3"
"4"
"5"
But in kannel logs and SMPP dump I've got flow like:
> "1"
< ok
> "2"
< ok
> "3"
< throttling error
#first timeout less than 1 minute according config
> "4"
< throttling error
#second timeout less than 1 minute according config, but in sum with first more than 1 minute
> "5"
< ok
> "3"
< ok
> "4"
< throttling error
and so on
So the order in result was "1", "2", "5", "3", "4" instead of "1", "2", "3", "4", "5".
Is it possible to change order type for attempt to send last failure message instead of next one in the chain?
In documentation I found sms-incoming-queue-limit option. But I have no idea what does "Value 0 means giving strict priority to outgoing messages" mean and unfortunately I can't run the tests soon. What is strict priority and what about queue\order type?
Many thanks.
SMPP Throttling error processing:
I did the following patch to smsc/smsc_smpp.c in "case submit_sm_resp:"
section from line 1609:
change
***
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
time(&(smpp->throttling_err_time));
else
smpp->throttling_err_time = 0;
bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s",
pdu->u.submit_sm_resp.command_status,
smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
***
to
***
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED) {
time(&(smpp->throttling_err_time));
/* Put the message back into the SMPP queue */
gw_prioqueue_produce(smpp->msgs_to_send, msg);
} else {
smpp->throttling_err_time = 0;
bb_smscconn_send_failed(smpp->conn, msg, reason,
octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
}
***
and in sms.c I have changed the function sms_priority_compare() to reverse
time sorting order (for some reason it was LIFO):
if (msg1->sms.time > msg2->sms.time)
ret = -1;
else if (msg1->sms.time < msg2->sms.time)
ret = 1;
-------------- next part --------------
Ordering of the composite SMS parts is based on additional comparison of their sms.id:
int sms_priority_compare(const void *a, const void *b)
{
int ret;
Msg *msg1 = (Msg*)a, *msg2 = (Msg*)b;
gw_assert(msg_type(msg1) == sms);
gw_assert(msg_type(msg2) == sms);
if (msg1->sms.priority > msg2->sms.priority)
ret = 1;
else if (msg1->sms.priority < msg2->sms.priority)
ret = -1;
else {
if (msg1->sms.time > msg2->sms.time)
ret = -1;
else if (msg1->sms.time < msg2->sms.time)
ret = 1;
else {
if (msg1->sms.id > msg2->sms.id)
ret = -1;
else if (msg1->sms.id < msg2->sms.id)
ret = 1;
else
ret = 0;
}
}
return ret;
}
My previous answer was wrong.
Сorrect answer:
Change function sms_priority_compare in sms.c:
if (msg1->sms.time > msg2->sms.time)
ret = 1;
else if (msg1->sms.time < msg2->sms.time)
ret = -1;
to
if (msg1->sms.time > msg2->sms.time)
ret = -1;
else if (msg1->sms.time < msg2->sms.time)
ret = 1;
else {
if (msg1->sms.id > msg2->sms.id)
ret = -1;
else if (msg1->sms.id < msg2->sms.id)
ret = 1;
else
ret = 0;
}
Change function smpp_status_to_smscconn_failure_reason in smsc/smsc_smpp.c:
static long smpp_status_to_smscconn_failure_reason(long status)
{
switch(status) {
case SMPP_ESME_RMSGQFUL:
case SMPP_ESME_RTHROTTLED:
case SMPP_ESME_RX_T_APPN:
case SMPP_ESME_RSYSERR:
return SMSCCONN_FAILED_TEMPORARILY;
break;
default:
return SMSCCONN_FAILED_REJECTED;
}
}
to
static long smpp_status_to_smscconn_failure_reason(long status)
{
switch(status) {
case SMPP_ESME_RMSGQFUL:
case SMPP_ESME_RX_T_APPN:
case SMPP_ESME_RSYSERR:
return SMSCCONN_FAILED_TEMPORARILY;
break;
case SMPP_ESME_RTHROTTLED:
return SMPP_ESME_RTHROTTLED;
break;
default:
return SMSCCONN_FAILED_REJECTED;
}
}
Change function handle_pdu in smsc/smsc_smpp.c (case submit_sm_resp:):
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
time(&(smpp->throttling_err_time));
else
smpp->throttling_err_time = 0;
bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
to
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
time(&(smpp->throttling_err_time));
else
smpp->throttling_err_time = 0;
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RMSGQFUL)
time(&msg->sms.time);
bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
Change function bb_smscconn_send_failed in bb_smscconn.c:
case SMSCCONN_FAILED_TEMPORARILY:
...
gwlist_produce(outgoing_sms, sms);
break;
case SMSCCONN_FAILED_SHUTDOWN:
gwlist_produce(outgoing_sms, sms);
break;
to
case SMSCCONN_FAILED_TEMPORARILY:
...
gwlist_produce(outgoing_sms, sms);
break;
case SMPP_ESME_RTHROTTLED:
gwlist_insert(outgoing_sms, 0, sms);
break;
case SMSCCONN_FAILED_SHUTDOWN:
gwlist_produce(outgoing_sms, sms);
break;
Change function handle_split in bb_smscconn.c:
case SMSCCONN_FAILED_TEMPORARILY:
...
gwlist_produce(outgoing_sms, msg);
break;
case SMSCCONN_FAILED_DISCARDED:
to
case SMSCCONN_FAILED_TEMPORARILY:
...
gwlist_produce(outgoing_sms, msg);
break;
case SMPP_ESME_RTHROTTLED:
gwlist_insert(outgoing_sms, 0, msg);
break;
case SMSCCONN_FAILED_DISCARDED:
I have written a code that have a if condition. After checking if then I want to show the results in a TexBox. The if statement is satisfied for more than one case and then I need to append them.
For example:
for (i=1;i<10;i++){
if (i > 8){
String^ Num = Convert::ToString(i);
textbox1->Text = Num;
}
}
The answer is 10. But I want to have 8,9,10.
How Could I have such a answer?
String^ Num = "";
for (i=1;i<10;i++){
if (i > 8){
Num = Convert::ToString(i);
if(Num == "")//first iteration so don't add ", "
{
textbox1-> += Num;
}
else
{
textbox1->Text += ", " + Num;
}
}
The default behavior of the string::operator+ is to concatenate so += will just concatenate whatever is already in the string with what the new value is. So assuming the Text field is a string this should work. Apologies for the lack of explanation.
I would like to replace every blank spaces in a string by a fixnum (which is the number of blank spaces).
Let me give an example:
s = "hello, how are you ?"
omg(s) # => "hello,3how10are2you1?"
Do you see a way (sexy if possible) to update a string like this?
Thank you Rubists :)
gsub can be fed a block for the "replace with" param, the result of the block is inserted into place where the match was found. The argument to the block is the matched string. So to implement this we capture as much whitespace as we can ( /\s+/ ) and feed that into the block each time a section is found, returning that string's length, which gets put back where the whitespace was originally found.
Code:
s = "hello, how are you ?"
res = s.gsub(/\s+/) { |m| m.length }
puts res
# => hello,3how10are2you1?
it is possible to do this via an array split : Javascript example
var s = "hello, how are you ?";
function omg( str ) {
var strArr = str.split('');
var count = 0;
var finalStr = '';
for( var i = 0; i < strArr.length; i++ ) {
if( strArr[i] == ' ' ) {
count++;
}
else
{
if( count > 0 ) {
finalStr += '' + count;
count = 0;
}
finalStr += strArr[i];
}
}
return finalStr
}
alert( omg( s ) ); //"hello,3how10are2you1?"
Lol, this seems the best it can be for javascript