print multicolumn formatted text vb6 - printing

i need to print formatted text like in the image below, how can i achive this in vb6, given that vb6 print object is not friendly for such this
The data i need to print that represented by the boxes are non related

It is not very difficult. You use the ScaleLeft, ScaleWidth, CurrentX, and CurrentY properties to set where printing begins on the page. In this case you will probably also want to set the Orientation property to vbPROPortrait. Using those positioning properties, and setting the font and style you want you then call Printer.Print
This method will draw 4 boxes onto a page. Play with the (x, y) coordinates or hard code the numbers to alter the sizes. Remove the .EndDoc statement if you don't want the printer to print the page from this method and call Printer.EndDoc from somewhere else. Full Printer object documentation for VB6 can be found at http://msdn.microsoft.com/en-us/library/aa443915%28v=vs.60%29.aspx
Private Sub DrawBox()
With Printer
.ScaleMode = vbTwips
lngScaleWidth = .ScaleWidth
lngScaleHeight = .ScaleHeight
Printer.Line (.ScaleLeft + lngMargin, .ScaleTop + lngMargin)-(lngScaleWidth / 2 - (100 + lngMargin * 2), lngScaleHeight / 2 - (100 + lngMargin * 2)), lngColor, B
Printer.Line (lngScaleWidth / 2 + (100 + lngMargin * 2), .ScaleTop + lngMargin)-(.ScaleWidth - lngMargin, lngScaleHeight / 2 - (100 + lngMargin * 2)), lngColor, B
Printer.Line (.ScaleLeft + lngMargin, lngScaleHeight / 2 + (100 + lngMargin * 2))-(lngScaleWidth / 2 - (100 + lngMargin * 2), .ScaleHeight - lngMargin), lngColor, B
Printer.Line (lngScaleWidth / 2 + (100 + lngMargin * 2), lngScaleHeight / 2 + (100 + lngMargin * 2))-(.ScaleWidth - lngMargin, .ScaleHeight - lngMargin), lngColor, B
.EndDoc
End With
End Sub
The sample code below demonstrates some of the positioning and other properties.
Dim lMargin as Integer
lMargin = 200
With Printer
.FontBold = True
.FontItalic = False
.CurrentY = .CurrentY + (3 * .TextHeight(App.ProductName))
.CurrentX = lLeftMargin
.FontName = "Arial"
.FontSize = 11
Printer.Print "Date " & strTransDate
End With

Related

How to shorten multiple If with ascending index of named ranges

I have a Google Spreadsheets formula like this with two named range: RangeA and RangeB.
=(1+VLOOKUP($A2,Test!RangeA,2,0)) * VLOOKUP($A2,Test!RangeA,3,0)
+ if(B2>=11,(index(Test!RangeB,1,2) - 1) * ((1+vlookup($A2,Test!RangeA,2,0))^(index(Test!RangeB,1,1)-1)) * vlookup($A2,Test!RangeA,3,0),0)
+ if(B2>=21,(index(Test!RangeB,2,2) - 1) * ((1+vlookup($A2,Test!RangeA,2,0))^(index(Test!RangeB,2,1)-1)) * vlookup($A2,Test!RangeA,3,0),0)
+ if(B2>=41,(index(Test!RangeB,3,2) - 1) * ((1+vlookup($A2,Test!RangeA,2,0))^(index(Test!RangeB,3,1)-1)) * vlookup($A2,Test!RangeA,3,0),0)
+ if(B2>=61,(index(Test!RangeB,4,2) - 1) * ((1+vlookup($A2,Test!RangeA,2,0))^(index(Test!RangeB,4,1)-1)) * vlookup($A2,Test!RangeA,3,0),0)
+ if(B2>=81,(index(Test!RangeB,5,2) - 1) * ((1+vlookup($A2,Test!RangeA,2,0))^(index(Test!RangeB,5,1)-1)) * vlookup($A2,Test!RangeA,3,0),0)
https://docs.google.com/spreadsheets/d/1_4Xc8PMXjUVuI2SXY3QgkqrYQn3xc922bYJjH0KHX2Q/edit?usp=sharing
The problem is: it contains many long if (it is much longer than the example above) which I think could be shortened since it increases the index 1 row per time. Please help.
Replace the INDEX with:
vlookup(row(indirect("1:"&match(B2,index(Test!RangeB,0,1)))),{row(Test!RangeB)-min(row(Test!RangeB))+1,Test!RangeB},3,false)
Keep the first IF and get rid of the rest:
=(1+VLOOKUP($A2,Test!RangeA,2,0)) * VLOOKUP($A2,Test!RangeA,3,0)
+ if(B2>=11,sumproduct((vlookup(row(indirect("1:"&match(B2,index(Test!RangeB,0,1)))),{row(Test!RangeB)-min(row(Test!RangeB))+1,Test!RangeB},3,false) - 1) * ((1+vlookup($A2,Test!RangeA,2,0))^(vlookup(row(indirect("1:"&match(B2,index(Test!RangeB,0,1)))),{row(Test!RangeB)-min(row(Test!RangeB))+1,Test!RangeB},2,false)-1)) * vlookup($A2,Test!RangeA,3,0)),0)

How to find and update levels accordingly based on points?

I am creating a rails application which is like a game. So it has points and levels. For example: to become level one the user has to get atleast 100 points and again for level two the user has to reach level 2 the user has to collect 200 points. The level difference changes after every 10 levels i.e., The difference between each level changes after 10 levels always. By that I mean the difference in points between level one and two is 100 and the difference in points in level 11 and 12 is 150 and so on. There is no upper bound for levels.
Now my question is let's say a user's total points is 3150 and just got updated to 3155. What's the optimal solution to find the current level and update it if needed?
I can get a solution using while loops and again looping inside it which will give a result in O(n^2). I need something better.
I think this code works but I'm not sure if this is the best way to go about it
def get_level(points)
diff = 100
sum = 0
level = -1
current_level = 0
while level.negative?
10.times do |i|
current_level += 1
sum += diff
if points > sum
next
elsif points <= sum
level = current_level
break
end
end
diff += 50
end
puts level
end
I wrote a get_points function (it should not be difficult). Then based on it get_level function in which it was necessary to solve the quadratic equation to find high value, and then calc low.
If you have any questions, let me know.
Check output here.
#!/usr/bin/env python3
import math
def get_points(level):
high = (level + 1) // 10
low = (level + 1) % 10
high_point = 250 * high * high + 750 * high # (3 + high) * high // 2 * 500
low_point = (100 + 50 * high) * low
return low_point + high_point
def get_level(points):
# quadratic equation
a = 250
b = 750
c = -points
d = b * b - 4 * a * c
x = (-b + math.sqrt(d)) / (2 * a)
high = int(x)
remainder = points - (250 * high * high + 750 * high)
low = remainder // (100 + 50 * high)
level = high * 10 + low
return level
def main():
for l in range(0, 40):
print(f'{l:3d} {get_points(l - 1):5d}..{get_points(l) - 1}')
for level, (l, r) in (
(1, (100, 199)),
(2, (200, 299)),
(9, (900, 999)),
(10, (1000, 1149)),
(11, (1150, 1299)),
(19, (2350, 2499)),
(20, (2500, 2699)),
):
for p in range(l, r + 1): # for in [l, r]
assert get_level(p) == level, f'{p} {l}'
if __name__ == '__main__':
main()
Why did you set the value of a=250 and b = 750? Can you explain that to me please?
Let's write out every 10 level and the difference between points:
lvl - pnt (+delta)
10 - 1000 (+1000 = +100 * 10)
20 - 2500 (+1500 = +150 * 10)
30 - 4500 (+2000 = +200 * 10)
40 - 7000 (+2500 = +250 * 10)
Divide by 500 (10 levels * 50 difference changes) and received an arithmetic progression starting at 2:
10 - 2 (+2)
20 - 5 (+3)
30 - 9 (+4)
40 - 14 (+5)
Use arithmetic progression get points formula for level = k * 10 equal to:
sum(x for x in 2..k+1) * 500 =
(2 + k + 1) * k / 2 * 500 =
(3 + k) * k * 250 =
250 * k * k + 750 * k
Now we have points and want to find the maximum high such that point >= 250 * high^2 + 750 * high, i. e. 250 * high^2 + 750 * high - points <= 0. Value a = 250 is positive and branches of the parabola are directed up. Now we find the solution of quadratic equation 250 * high^2 + 750 * high - points = 0 and discard the real part (is high = int(x) in python script).

OpenCV bilinear downsampling with non-integer scaling

I need help in figuring out the algorithm/implementation OpenCV is using for image-downsampling with non-linear scaling factors.
I know the question was already ask a few times, but most answers seem to not match OpenCV's implementation (for instance, this answer is not correct when using OpenCV: https://math.stackexchange.com/questions/48903/2d-array-downsampling-and-upsampling-using-bilinear-interpolation).
Minimal problem formulation:
I want to downsample an image of resolution 4x4 to an image of resolution 3x3 using bilinear interpolation. I am interested in the interpolation coefficients.
Example in python:
img = np.asarray([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]]).astype(np.float32)
img_resized = cv2.resize(img, (3, 3), 0, 0, cv2.INTER_LINEAR).astype(np.float32)
print(img)
# [[ 1. 2. 3. 4.]
# [ 5. 6. 7. 8.]
# [ 9. 10. 11. 12.]
# [13. 14. 15. 16.]]
print(img_resized)
# [[ 1.8333333 3.1666667 4.5 ]
# [ 7.166667 8.5 9.833333 ]
# [12.5 13.833333 15.166666 ]]
Interpolation coefficients:
After a lot of trial-and-error, I figured out the interpolation coefficients OpenCV is using for this specific case.
For the corner points of the 3x3 image:
1.8333333 = 25/36 * 1 + 5/36 * 2 + 5/36 * 5 + 1/36 * 6
4.5000000 = 25/36 * 4 + 5/36 * 3 + 5/36 * 8 + 1/36 * 7
12.5000000 = 25/36 * 13 + 5/36 * 9 + 5/36 * 14 + 1/36 * 10
15.1666666 = 25/36 * 16 + 5/36 * 15 + 5/36 * 12 + 1/36 * 11
For the middle points of the 3x3 image:
8.5 = 1/4 * 6 + 1/4 * 7 + 1/4 * 10 + 1/4 * 11
For the remaining 4 points of the 3x3 image:
3.1666667 = 5/12 * 2 + 5/12 * 3 + 1/12 * 6 + 1/12 * 7
7.1666667 = 5/12 * 5 + 5/12 * 9 + 1/12 * 6 + 1/12 * 10
9.8333333 = 5/12 * 8 + 5/12 * 12 + 1/12 * 7 + 1/12 * 11
13.833333 = 5/12 * 14 + 5/12 * 15 + 1/12 * 10 + 1/12 * 11
Question:
Can someone please help me make sense of these interpolation coefficients? How are they calculated? I tried to read the source of the cv::resize() function, but it did not help me a lot :S
After playing around with various test cases, I think I know the answer to how OpenCV chooses the sample point locations. As #ChrisLuengo has pointed out in a comment, OpenCV seems to not apply a low-pass filter before downsampling, but uses (bi-)linear interpolation only.
(Possible) Solution:
Let's assume we have a 5x5 image, which pixel positions are represented with the blue circles in the graphic below. We now want to downsample it to a 3x3, or a 4x4 image, and need to find the sample positions of the new downsampled image in the original image grid.
It appears to be that OpenCV uses pixel distance of 1 for the original image grid, and a pixel distance of (OLD_SIZE / NEW_SIZE), thus here 5/3 and 5/4, for the new image grid. Moreover, it aligns both grids at the center point. Thus, OpenCV's deterministic sampling algorithms can be visualized as follows:
Visualization 5x5 to 3x3:
Visualization 5x5 to 4x4:
Sample Code (Python 2.7):
import numpy as np
import cv2
# 1. H_W is the height & width of the original image, using uniform H/W for this example
# resized_H_W is the height & width of the resized image, using uniform H/W for this example
H_W = 5
resized_H_W = 4
# 2. Create original image & Get OpenCV resized image:
img = np.zeros((H_W, H_W)).astype(np.float32)
counter = 1
for i in range(0, H_W):
for j in range(0, H_W):
img[i, j] = counter
counter += 1
img_resized_opencv = cv2.resize(img, (resized_H_W, resized_H_W), 0, 0, cv2.INTER_LINEAR).astype(np.float32)
# 3. Get own resized image:
img_resized_own = np.zeros((resized_H_W, resized_H_W)).astype(np.float32)
for i in range(0, resized_H_W):
for j in range(0, resized_H_W):
sample_x = (1.0 * H_W) / 2.0 - 0.50 + (i - (1.0 * resized_H_W - 1.0) / 2.0) * (1.0 * H_W) / (1.0 * resized_H_W)
sample_y = (1.0 * H_W) / 2.0 - 0.50 + (j - (1.0 * resized_H_W - 1.0) / 2.0) * (1.0 * H_W) / (1.0 * resized_H_W)
pixel_top_left = img[int(np.floor(sample_x)), int(np.floor(sample_y))]
pixel_top_right = img[int(np.floor(sample_x)), int(np.ceil(sample_y))]
pixel_bot_left = img[int(np.ceil(sample_x)), int(np.floor(sample_y))]
pixel_bot_right = img[int(np.ceil(sample_x)), int(np.ceil(sample_y))]
img_resized_own[i, j] = (1.0 - (sample_x - np.floor(sample_x))) * (1.0 - (sample_y - np.floor(sample_y))) * pixel_top_left + \
(1.0 - (sample_x - np.floor(sample_x))) * (sample_y - np.floor(sample_y)) * pixel_top_right + \
(sample_x - np.floor(sample_x)) * (1.0 - (sample_y - np.floor(sample_y))) * pixel_bot_left + \
(sample_x - np.floor(sample_x)) * (sample_y - np.floor(sample_y)) * pixel_bot_right
# 4. Print results:
print "\n"
print "Org. image: \n", img
print "\n"
print "Resized image (OpenCV): \n", img_resized_opencv
print "\n"
print "Resized image (own): \n", img_resized_own
print "\n"
print "MSE between OpenCV <-> Own: ", np.mean(np.square(img_resized_opencv - img_resized_own))
print "\n"
Disclaimer:
This is just my theory that I tested via ~10 test cases. I do not claim that this is 100% true.

Getting probability of class using naive Bayes

I am trying to classify input with two classes, here is the code. dino and crypto are two classes:
for w, cnt in list(counts.items()): #count is dict with word and it's count value
p_word = vocab[w] / sum(vocab.values())
p_w_given_dino = (word_counts["dino"].get(w, 0.0) + 1) / (sum(word_counts["dino"].values()) + v)
p_w_given_crypto = (word_counts["crypto"].get(w, 0.0) + 1) / (sum(word_counts["crypto"].values()) + v)
log_prob_dino += math.log(cnt * p_w_given_dino / p_word)
log_prob_crypto += math.log(cnt * p_w_given_crypto / p_word)
print("Score(dino) :", math.exp(log_prob_dino + math.log(prior_dino)))
print("Score(crypto):", math.exp(log_prob_crypto + math.log(prior_crypto)))
Another approach is:
prior_dino = (priors["dino"] / sum(priors.values()))
prior_crypto = (priors["crypto"] / sum(priors.values()))
for w, cnt in list(counts.items()):
p_word = vocab[w] / sum(vocab.values())
p_w_given_dino = (word_counts["dino"].get(w, 0.0) + 1) / (sum(word_counts["dino"].values()) + v)
p_w_given_crypto = (word_counts["crypto"].get(w, 0.0) + 1) / (sum(word_counts["crypto"].values()) + v)
prob_dino *= p_w_given_dino
prob_crypto *= p_w_given_crypto
t_prior_dino = prob_dino * prior_dino
t_prior_crypto = prob_crypto * prior_crypto
On the second approach I got very small values.
Which one is correct, or are both of them correct?
These are completely equivalent approaches. The first one however is the preferable one, as working on logarithms of probabilities makes the whole process more numericaly stable. Results should be identical (up to numerical errors).
However it appears that you have errors in second approach
prob_dino *= p_w_given_dino
does not use the fact, that you have cnt occurences; it should be something like
prob_dino *= pow(p_w_given_dino, cnt)

Need help getting for loop to iterate correctly

I am working on this for homework, and I have most of this done my problem is there is something wrong in one of the for loops as the display I get is only one line when it should be a line for every value in the range 50,000 - 60,000 with a step value of 50.
def computeTax(status, taxableIncome):
print("Taxable Income/" + "\t" + "Single/" + "\t" + "Married Joint/" + \
"\t" + "Married Separate/" + " " + "Head of Household")
for taxableIncome in range(50000, 60001, 50):
for status in range(1, 5, 1):
if (status == 1): #tax calculation for single person
tax1 = 8350 * .10 + (33950 - 8350) * 0.15 + \
(taxableIncome - 33950) * 0.25
tax1 = round(tax1,0)
if (status == 2): #tax calculation for married file jointly
tax2 = 16700 * .10 + (67900 - 16700) * 0.15 + \
(taxableIncome - 67900) * 0.15
tax2 = round(tax2,0)
if (status == 3): #tax calculation for married file separately
tax3 = 8350 * .10 + (33950 - 8350) * 0.15 + \
(taxableIncome - 33950) * 0.25
tax3 = round(tax3,0)
if (status == 4): #tax calculation for head of household
tax4 = 11950 * .10 + (45500 - 11950) * 0.15 + \
(taxableIncome - 45500) * 0.25
tax4 = round(tax4,0)
print(str(tax1) + "\t" + str(tax2) + "\t" + str(tax3) + "\t" + str(tax4))
return (status, taxableIncome)
computeTax(range(1, 5, 1),range(50000, 60001, 50))
I'm not familiar with python, but do you have to define code blocks like you would with PHP?
EG
if (status == 1): #tax calculation for single person
{
tax1 = 8350 * .10 + (33950 - 8350) * 0.15 + \
(taxableIncome - 33950) * 0.25
tax1 = round(tax1,0)
}
Like I said; not familiar with Python, but I thought I might have an answer for you; if I'm completely off then sorry and good luck.

Resources