Autohotkey_L numeric comparison issue - object

I have a script looping for 8 numbers, skipping negative and return the largest as follows:
biggest = 0
entry = 0
loop, 8
{
; MsgBox %A_Index%
if NegativeReadings%A_Index% not contains - ;filter out readings that are negative
{
; MsgBox % AttributeReadings%A_Index%
MsgBox %biggest%
; MsgBox % AttributeReadings%A_Index%
if (AttributeReadings[A_Index] > biggest)
{
biggest := AttributeReadings[A_Index]
entry = %A_Index%
}
}
}
MsgBox %entry%
When I feed in some a sample image with 100,100,150,100,50,100,110,75, the OCR returns the object array result correctly but the numeric comparison fails
I'm getting MsgBox %biggest% = 0,100,100,150,150,50,50,50 => %entry% = 8
Something wrong happens in between (50 > 150) I have little clue in dealing with data types in ahk, any help is welcomed

Ok, I figured it out on second shot tonight, the OCR is returning a string with tailing spaces, so it led to alphabetic comparison as mentioned by admin.
Trimmed it with regexp now it works just fine
Here is the code snippet for anyone who may come across this similar issue
#SingleInstance force
#Include OCR.ahk
; sleep 5000
OCR()
; global
{
AttributeReadings := Object()
loop, 8
{
NegativeReadings%A_Index% := GetOCR(730, (136 + (17 * (A_Index - 1))), 35, 17)
AttributeReadings[A_Index] := GetOCR(730, (136 + (17 * (A_Index - 1))), 35, 17, "numeric")
; MsgBox % AttributeReadings%A_Index%
}
biggest = 0
entry = 0
i = 0
loop, 8
{
; MsgBox %A_Index%
if NegativeReadings%A_Index% not contains - ;filter out readings that are negative
{
; MsgBox % AttributeReadings%A_Index%
; length := StrLen(biggest)
; MsgBox %biggest%, %length%
number := RegExReplace(AttributeReadings[A_Index], "([space])?", "")
MsgBox %number%
; MsgBox % AttributeReadings%A_Index%
if (number > biggest)
{
biggest := number
entry := i
}
}
i++
}
MsgBox %entry%
}
End::
OCR()
return
The code above basically reads in a list of numbers from an image and return the first largest non-negative. As to the negative filtering part, it's done in OCR since it's ok with my test cases, you may want to modify it depending what images you're working with

Related

Program keeps printing one extra line then what the user inputs

I'm having some trouble trying to build a pyramid out of "#" for mario.c in problem set 1. My program seems to be having some trouble with handling input.
I get these errors:
:( handles a height of 1 correctly
expected ""#"", not "" #"\n"##""
:( handles a height of 2 correctly
expected "" #"\n"##"", not "" #"\n" ##"\n..."
:( handles a height of 8 correctly
expected "" #"\n" ...", not "" #"\n"..."
:( rejects a height of 9, and then accepts a height of 2
expected "" #"\n"##"", not "" #"\n" ##"\n..."
Here is my code:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
height = get_int("How many rows for the pyramid?\n");
}
while (height < 1 || height > 8); //This loops until the user input 1 - 8 rows
for (int row = 0; row <= height; row++) //This says to print a new row until it reaches the user inputted height
{
for (int spaces = (height - (row + 1)); spaces >= 0; spaces--) //This formula prints less spaces as more rows are printed
{
printf(" ");
}
for (int hashes = 1; hashes <= (row + 1); hashes++) //This formula prints more hashes as more rows are printed
{
printf("#");
}
printf("\n");
}
}
Any help is appreciated!!
Your code prints an extra line of hashtags creating a pyramid which is 1 greater in height than the user input. You can see this in the error message you get:
:( handles a height of 1 correctly expected ""#"", not "" #"\n"##""
Hence, the output of your program is #\n## which equates to
#
##
The required output for a height of 1 is:
#
To fix your issue, you have to iterate through your code one lesser time than you do currently for any number. Hence, perhaps consider changing the condition: row <= height; in your for loop.
Consider changing the comparison to just <. By doing this, the code inside the for loop will run one lesser time.

Type mismatch in AutoHotkey Excel

I am trying to get input from a user, lookup the input value in an Excel column and return the value of the cell on the right side of the matching value.
This is what I came up with. As long as I replace %index% with a number, it will return a value from the Excel file.
The error I receive tells me there is a 'type mismatch' where I use %index% in
value := workbook.Sheets("Sheet1").Cells(%index%, 1).Value
Any ideas how to fix the type mismatch?
#a::
workbook := ComObjGet("somepath\tester.xlsx")
InputBox, OutputVar, Question 1, What are you looking for?
if (OutputVar)
MsgBox, Let me do this for you.
intent = OutputVar
index = 1
value = ""
Loop {
index := %index% + 1
value := workbook.Sheets("Sheet1").Cells(%index%, 1).Value
}
Until %intent% = %value%
SendInput, workbook.Sheets("Sheet1").Cells(%index%, 2).Value
Return
Use index, not %index%, in expressions. Also, you can use the built-in A_INDEX variable inside of loops
Here's your corrected code:
#a::
workbook := ComObjGet("somepath\tester.xlsx")
MAX_ROWS := 10
InputBox intent, Question 1, What are you looking for?
if ( ErrorLevel == 0 && intent ) {
Loop %MAX_ROWS% {
if ( intent == workbook.Sheets("Sheet1").Cells(A_Index, 1).Value ) {
SendInput % workbook.Sheets("Sheet1").Cells(A_Index, 2).Value
return
}
}
MsgBox 48, Not Found, "%intent%" not found in column a
}
return
Notes:
You cannot use substitution when a command takes an expression
ErrorLevel == 0 means OK was pressed. See InputBox
SendInput % makes the line use expression mode; everything following "% " is evaluated as an expression
Your loop never exits if intent is not found in the spreadsheet

Check length using String method length

This has been bugging me for three days. I'm attempting to read text from a text field, check the length of the value is greater than zero (using the String method length), then create a loop. If the length is not greater than zero, I have to set an error message and an error flag (boolean variable to true). I've dug into the documentation for the String method but I can't seem to get length() to work for me. You can see my experimenting with the code. First time posting, sorry if I'm getting this wrong.
private void setShipmentProperties() {
ship.setEmployeeNum(empNumTF.getText());
if(ship.setEmployeeNum(String(length()) < 0)) {
isDataEntryError = true;
msgLbl.setText("Pay rate must be a numeric " + "value: 1, 2, 3...");
}
ship.setShipmentNum(shipNumTF.getText(this.length()));
if(this.length() < 0) {
isDataEntryError = true;
msgLbl.setText("Pay rate must be a numeric " + "value: 1, 2, 3...");
}
ship.setSupplierName(supplTF.getText());
if(ship.length() < 0) {
isDataEntryError = true;
msgLbl.setText("Pay rate must be a numeric " + "value: 1, 2, 3...");
}
}
A length can't be < 0. The length of a string can't be less than zero.

Go: convert rune (string) to string representation of the binary

This is just in case someone else is learning Golang and is wondering how to convert from a string to a string representation in binary.
Long story short, I have been looking at the standard library without being able to find the right call. So I started with something similar to the following:
func RuneToBinary(r rune) string {
var buf bytes.Buffer
b := []int64{128, 64, 32, 16, 8, 4, 2, 1}
v := int64(r)
for i := 0; i < len(b); i++ {
t := v-b[i]
if t >= 0 {
fmt.Fprintf(&buf, "1")
v = t
} else {
fmt.Fprintf(&buf, "0")
}
}
return buf.String()
}
This is all well and dandy, but after a couple of days looking around I found that I should have been using the fmt package instead and just format the rune with %b%:
var r rune
fmt.Printf("input: %b ", r)
Is there a better way to do this?
Thanks
Standard library support
fmt.Printf("%b", r) - this solution is already very compact and easy to write and understand. If you need the result as a string, you can use the analog Sprintf() function:
s := fmt.Sprintf("%b", r)
You can also use the strconv.FormatInt() function which takes a number of type int64 (so you first have to convert your rune) and a base where you can pass 2 to get the result in binary representation:
s := strconv.FormatInt(int64(r), 2)
Note that in Go rune is just an alias for int32, the 2 types are one and the same (just you may refer to it by 2 names).
Doing it manually ("Simple but Naive"):
If you'd want to do it "manually", there is a much simpler solution than your original. You can test the lowest bit with r & 0x01 == 0 and shift all bits with r >>= 1. Just "loop" over all bits and append either "1" or "0" depending on the bit:
Note this is just for demonstration, it is nowhere near optimal regarding performance (generates "redundant" strings):
func RuneToBin(r rune) (s string) {
if r == 0 {
return "0"
}
for digits := []string{"0", "1"}; r > 0; r >>= 1 {
s = digits[r&1] + s
}
return
}
Note: negative numbers are not handled by the function. If you also want to handle negative numbers, you can first check it and proceed with the positive value of it and start the return value with a minus '-' sign. This also applies the other manual solution below.
Manual Performance-wise solution:
For a fast solution we shouldn't append strings. Since strings in Go are just byte slices encoded using UTF-8, appending a digit is just appending the byte value of the rune '0' or '1' which is just one byte (not multi). So we can allocate a big enough buffer/array (rune is 32 bits so max 32 binary digits), and fill it backwards so we won't even have to reverse it at the end. And return the used part of the array converted to string at the end. Note that I don't even call the built-in append function to append the binary digits, I just set the respective element of the array in which I build the result:
func RuneToBinFast(r rune) string {
if r == 0 {
return "0"
}
b, i := [32]byte{}, 31
for ; r > 0; r, i = r>>1, i-1 {
if r&1 == 0 {
b[i] = '0'
} else {
b[i] = '1'
}
}
return string(b[i+1:])
}

Lua script optimization

I am trying to connect redis via c# using using ServiceStack.Redis.
I have written below code to validate number based on the key specified.
argv[1] is key
argv[2] is number
string strScript = " local intCurrentVal = redis.call('GET', '' .. ARGV[1] .. ''); \n"
+ "if (tonumber(intCurrentVal) <= 0 ) then return 1 elseif ( (tonumber(intCurrentVal)) - (tonumber('' .. ARGV[2] .. '')) < 0 ) then return 0 end;"
+ "local intUpdatedVal = redis.call('SET', '' .. ARGV[1] .. '',( intCurrentVal - tonumber('' .. ARGV[2] .. '')));"
+ "local intCurr = redis.call('GET', '' .. ARGV[1] .. ''); return intCurr";
logical steps:
get the current value
check if current value should not be less then or equal to 0
check if current value - passed value should not be less then O
if current value - passed is not less then 0 then set the (current value - passed) as the current value
get the current value
Is it possible to optimize and tune the following lua script for performance. please help.
Original formatting is awful -- so is often performance.
local key = tostring(ARGV[1])
local number = tonumber(ARGV[2])
local current = tonumber(redis.call('GET', key))
if current <= 0 then
return 1
elseif current < number then
return 0
end
redis.call('SET', key, current - number)
return redis.call('GET', key)
Further optimization steps may include: localizing of global functions (like to string, tonumber, etc.), caching compiled chunk at LUA_REGISTRYINDEX table.

Resources