Order a Multiline Textboxes by Character Number - vb.net

I want to order a Multiline by character, this code should do this, unfortunately it does not.
Dim strs = New String() {TxtListScanTxt.Text}
Dim sorted = strs.OrderBy(Function(x) x.Length).ThenBy(Function(x) x).ToArray()
TxtListScanTxt.Lines = sorted
Output
1,2,3,4,5
1,2,3,9
1,2,4,8
1,2,5,7
3,12
4,5,6
7,8
15
Output: Expected:
15
7,8
3,12
4,5,6
1,2,5,7
1,2,4,8
1,2,3,9
1,2,3,4,5

This would be easy if you didn't want to sort lists of numbers individually. Also, since you are sorting the individual lists (of the same count) by numeric items, you can't use a string sort. What I mean is
9,5
10,6
How do you sort that? You would compare 9 with 1, in 9 and 10, respectively, if doing an alphabetical sort, and 9 would be greater than 10. I think you should parse each individual element as an integer beforehand.
So my code here is complex, and involves grouping the lines by item count first, then ordering the lines within their groups. I suppose this could be put into one line but this is more readable (though, still not very...)
Dim lines = TxtListScanTxt.Lines.Select(Function(l) l.Split(","c).Select(Function(s) Integer.Parse(s)))
Dim groups = lines.GroupBy(Function(l) l.Count()).OrderBy(Function(g) g.Key)
Dim sortedGroups = groups.Select(Function(g) g.OrderByDescending(Function(gi) gi.Reverse().Select(Function(i, v) v * 10 ^ i).Sum())).SelectMany(Function(g) g)
Dim result = sortedGroups.Select(Function(g) String.Join(",", g))
TxtListScanTxt.Lines = result.ToArray()
Recursion could be used to do sort each sub group by their numbers, but we could also take a sum, and I'm trying to do this with LINQ. The magic in Function(i, v) v * 10 ^ i).Sum() is that we will sort by creating a number out of your list by multiplying each successive item by 10 to a higher order of magnitude then summing.
1,2,3,9 = 1000 * 1 + 100 * 2 + 10 * 3 + 9 = 1239
1,2,4,8 = 1000 * 1 + 100 * 2 + 10 * 4 + 8 = 1248
and 1248 should come before 1239 (so order by descending for these sub groups)
You could say concatenate the characters into an integer but once you get into double digits, that breaks down. This method handles that case.

You can try to split the text in multiple lines before try to order the lines:
The TextBox has a Lines property that already gives an Array containing each line of the Text.
Dim Lines() As String = TxtListScanTxt.Lines ' System.IO.File.ReadAllLines("C:\temp\myfile.txt") ' TxtListScanTxt.Text.Split({Environment.NewLine}, StringSplitOptions.None) ' You can use this if you want to split the text from a string
Dim SortedLines = Lines.OrderBy(Function(Line) Line.Length).ToArray()
TxtListScanTxt.Lines = SortedLines
Initial screen:
Result after sort:

Related

How to find every combination of a binary 16 digit number

I have 16 different options in my program and i have a 16 character variable which is filled with 1's or 0's depending on the options that are selected (0000000000000000 means nothing is selected, 0010101010000101 means options 3,5,7,9,14 and 16 are selected, 1111111111111111 means everything is selected.)
When i run my program, the code looks (using an if statement) for a 1 in the designated character of the 16 digit number and if there is one there then it runs the code for that option, otherwise it skips it..
e.g option 3 looks too see if the 3rd character (0010000000000000) is a 1 and if it is it runs the code.
Now what i am trying to do is generate a list of every different combination that is possible so I can create an option for it to just loop through and run every possible option:
0000000000000001
0000000000000010
0000000000000011
...
1111111111111100
1111111111111110
1111111111111111
I have tried this but i think it may take a couple of years to run jaja:
Dim binString As String
Dim binNUM As Decimal = "0.0000000000000001"
Do Until binNUM = 0.11111111111111111
binString = binNUM.ToString
If binString.Contains(1) Then
If binString.Contains(2) Or binString.Contains(3) Or binString.Contains(4) Or binString.Contains(5) Or binString.Contains(6) Or binString.Contains(7) Or binString.Contains(8) Or binString.Contains(9) Then
Else
Debug.Print(binNUM)
End If
End If
binNUM = binNUM + 0.0000000000000001
After the code above is complete i would then take the output list and remove any instances of "0." and then any lines which had fewer than 16 chararcters (because the final character would be a 0 and not show) I would add a 0 until there was 16 characters. I know this bit might be stupid but its as far a ive got
Is there a faster way I can I generate a list like this in VB.net?
You should be able to get the list by using Convert.ToString as follows:
Dim sb As New System.Text.StringBuilder
For i As Integer = 0 To 65535
sb.AppendLine(Convert.ToString(i, 2).PadLeft(16, "0"c))
Next
Debug.Print(sb.ToString())
BTW: This should finish in under one second, depending on your system ;-)
Create an enum with FlagAttributes, which allows you to do the key functions you list. Here is an example of setting it up in a small project I am working on:
<FlagsAttribute>
Public Enum MyFlags As Integer
None = 0
One = 1
Two = 2
Three = 4
Four = 8
Five = 16
Recon = 32
Saboteur = 64
Mine = 128
Headquarters = 256
End Enum
e.g.
Dim temp as MyFlags
Dim doesIt as Boolean
temp = MyFlags.One
doesIt = temp.HasFlag(MyFlags.Two)
temp = temp OR MyFlags.Three
'etc.
The real advantage is how it prints out, if you want something other than 0, 1 and is much more human friendly.

Extracting a word from string from n rows and append that word as a new col in SQL Server

I have got a data set that contains 3 columns and has 15565 observations. one of the columns has got several words in the same row.
What I am looking to do is to extract a particular word from each row and append it to a new column (i will have 4 cols in total)
The problem is that the word that i am looking for are not the same and they are not always on the same position.
Here is an extract of my DS:
x y z
-----------------------------------------------------------------------
1 T 3C00652722 (T558799A)
2 T NA >> MSP: T0578836A & 3C03024632
3 T T0579010A, 3C03051500, EAET03051496
4 U T0023231A > MSP: T0577506A & 3C02808556
8 U (T561041A C72/59460)>POPMigr.T576447A,C72/221816*3C00721502
I am looking to extract all the words that start with 3Cand are 10 characters long and then append the to a new col so it looks like this:
x y z Ref
----------------------------------------------------------------
1 T 3C00652722 (T558799A) 3C00652722
2 T NA >> MSP: T0578836A & 3C03024632 3C03024632
3 T T0579010A, 3C03051500, EAET03051496 3C03051500
4 U T0023231A > MSP: T0577506A & 3C02808556 3C02808556
8 U >POPMigr.T576447A,C72/221816*3C00721502 3C00721502
I have tried using the Contains, Like and substring methods but it does not give me the results i am looking for as it basically finds the rows that have the 3C number but does not extract it, it just copies the whole cell and pastes is on the Ref column.
SQL Server doesn't have good string functions, but this should suffice if you only want to extract one value per row:
select t.*,
left(stuff(col,
1,
patindex('%3C[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', col),
''
), 10)
from t ;

How to get the last number of a string using selenium webdriver

1 - 2 of 2
Above is my text. This is from paging of a web application. How do i extract the last number of the above text. SO i will get the count of list in that page and i can run a loop with respect to the number.
You can use substring
Let's consider your example. You have a String 1 - 2 of 2 (pagination probably)
Each of individual character is a specified index of a String
1 = 0
space = 1
- = 2
space = 3
etc.
String has a set of methods to perform various tasks. One of them is length() which gives you number of characters in your String
What you can do is to pass your length of String to substring.
Example:
myString.substring(0,1) will give you results of 1
myString.substring(0,myString.length()) wil give you results of 1 - 2 of 5
Additional info: myString.length() is an int type so you can perform math operations like + or -
myString.substring(0,myString.length()-1) will give you results of 1 - 2 of
I gave you the tools, now it's time for you to find the solutions.
You could just split the string using the spaces and then grab the last element of the split array. That should cover you even if the last number has more than one digit. Throw in a trim, just in case, to remove any leading/trailing white space.
String[] splitter = pageCount.trim().split(" ");
System.out.println(splitter[splitter.length - 1]);

Concatenating string and integers in pandas dataframe(based on conditions)

In my dataframe I have 2 columns:
Country index(For example SK)
id_number(usually 8 digit,for example:98341852)
I want to concatenate them and it's easy:
sk_df['id'] = sk_df['country index'].str.cat(sk_df['id_number'].values.astype(str))
But some of rows in column id_number has number of digits less than 8. In this case I want to add zeros as separator between Country index and id_number(for example, if length of id_number is 6 I want to add 8-6 = 2 zeros between variables: SK00813841. If id_number length is 7,than add 1 zero etc)
I tried this:
def indexing(row):
if row['id_number'].astype(str).str.len() == 8:
return row['country index'].str.cat(row['id_number'].values.astype(str))
else:
sep_mult = 8 - row['id_number'].astype(str).str.len()
return row['country index'].str.cat(row['id_number'].values.astype(str),sep = '0'*sep_mult)
sk_df['id'] = sk_df.apply(lambda row: indexing(row),axis = 1)
But it doesn't work.
How can I do it?
Use .zfill():
sk_df['id'] = sk_df['country index'] + sk_df['id_number'].astype(str).str.zfill(8)

Selecting random tuple from bag

Is it possible to (efficiently) select a random tuple from a bag in pig?
I can just take the first result of a bag (as it is unordered), but in my case I need a proper random selection.
One (not efficient) solution is counting the number of tuples in the bag, take a random number within that range, loop through the bag, and stop whenever the number of iterations matches my random number. Does anyone know of faster/better ways to do this?
You could use RANDOM(), ORDER and LIMIT in a nested FOREACH statement to select one element with the smallest random number:
inpt = load 'group.txt' as (id:int, c1:bytearray, c2:bytearray);
groups = group inpt by id;
randoms = foreach groups {
rnds = foreach inpt generate *, RANDOM() as rnd; -- assign random number to each row in the bag
ordered_rnds = order rnds by rnd;
one_tuple = limit ordered_rnds 1; -- select tuple with the smallest random number
generate group as id, one_tuple;
};
dump randoms;
INPUT:
1 a r
1 a t
1 b r
1 b 4
1 e 4
1 h 4
1 k t
2 k k
2 j j
3 a r
3 e l
3 j l
4 a r
4 b t
4 b g
4 h b
4 j d
5 h k
OUTPUT:
(1,{(1,b,r,0.05172709255901231)})
(2,{(2,k,k,0.14351660053632986)})
(3,{(3,e,l,0.0854104195792681)})
(4,{(4,h,b,8.906013598960483E-4)})
(5,{(5,h,k,0.6219490873384448)})
If you run "dump randoms;" multiple times, you should get different results for each run.
Writing a UDF might give you better performance as you do not need to do secondary sort on random within the bag.
I needed to do this myself, and found surprisingly that a very simple answer seems to work, to get about 10% of an alias A:
B = filter A by RANDOM() < 0.1