Jump to content
UBot Underground

Recommended Posts

This looks like being a big issue for many (newbies especially), so I thought I would explain the following code a lil' bit.

 

Feel free to also use it as a Custom Function anytime you need.

 

It would have been even simpler, but to make it usable in many instances, I have generalized the problem a little bit.

 

Let's assume we have a text like:

 

"
I code in UBot Studio daily and I'm happy!
"
  • and we'd like to separate the left wing of it, starting from the beginning upto the text "Ubot "
  • and the right wing of it, starting after the text "Ubot "

We seek to obtain these results:

  • left wing becomes --> "I code in "
  • right wing becomes --> "Studio daily and I'm happy!"

First we shall build a custom command with three input parameters:

  • the text to be split
  • the separator text
  • the side of the initial text we want to return

define $ChooseWing(#var_TEXT, #var_Separator, #var_Wing) {
}

 

We shall NOT FORGET to add a RETURN command at the end before the Custom Command Function's exit, but we will get to that later...

 

Now, let's calculate the various text parts' lengths so we can then manipulate the substrings:

 

We need to find the total text length first using the $text length() function/parameter

 

set(#var_String_Length, $text length(#var_TEXT), "Local")

 

NB:

Because this will be used as a custom function, all variables within its code are set to "Local"

However, in case you wanna see them in action in your DEBUGGER, you need to set them to "Global". Once you understood how the code works and especially WHY and made sure there are no errors, switch back all the variables to "Local" and save your .ubot file and code.

 

In our given example, we have 42 characters.

 

Next, we shall calculate the length of the left wing of the given string, starting from the beginning, until we find the separator text we seek.

 

We shall use the the $find index() function/parameter to get the position in the string where the separator string STARTs:

 

set(#var_Left_Wing_Length, $find index(#var_TEXT, #var_Separator), "Local")

 

The result is 10. Here is WHY:

 

I_code_in_

 

1234567891

_________
0

 

I used "_" to symbolize the spaces/blanks so that you can see the counter easily.

 

So, the left wing side of the text will have 10 characters in length (for other programatically purposes, you may choose to TRIM this later to remove the trailing blank etc... but this is not what we need here at this moment)

 

Now let's calculate first the length of the separator text itself:

 

set(#var_Separator_Length, $text length(#var_Separator), "Local")

 

In most cases, people would actually use a single character as a separator, such as a dot within a domain name, to separate the actual domain name from its TLD, such as separating:

 

mydomain
.
com
into....
mydomain
&
com
left
/
right
wings, using
.
as the one char length separator

 

However, for the purpose of generalization, I have written the function with a variable separator text and of course, variable length, accordingly.

 

The result is 5. I have used the text "UBot " for the separator (notice the trailing blank space there)

 

Now, we need to find the position in the initial text string where the separator ends and of course, the right wing starts:

 

set(#var_Separator_End_Position, $add(#var_Left_Wing_Length, #var_Separator_Length), "Local")

 

We basically added the value of the starting position of the separator text and its known length using the $add() function/parameter.

 

The result is 15 (10+5).

 

Finally, we need to find the length of the right wing.

This is where people usually get errors, because while the left wing obviously starts at 0 position and it ends where the find index says the separator starts, the end of the string is variable depending on the initial text length, BUT it's not an issue for us here anymore, as we have all we need to calculate this value, by now:

 

set(#var_Right_Wing_Length, $subtract(#var_String_Length, #var_Separator_End_Position), "Local")

 

We simply deducted from the total length of the initial string, the position where the right wing starts, that we calculated before using the $subtract() function/parameter

 

The result is 27 (42-15).

 

Everything is now known and set, we only need to decide which part of the text our custom function will return (as the UBot Studio Custom Functions will return a single value, obviously)

 

In order to make things even more general, I employed an IF here to decide which wing to be processed, accepting as the comparison variable any text starting with either L (or l for that matter) for the LEFT WING and then any text for the right wing, basically, assuming you guys know what to input there.

 

However, to avoid potential errors, these choices should be programmed and not left somehow at user's will, also to make sure there is no room for error, the ELSE branch of my IF that accepts anything into it, might have been an ELSE IF looking for the letter R or r for the side string and the last ELSE branch might be made to return an error, etc...

 

However, as it is not the purpose of this tutorial, I used a very simple IF only, on each branch of it using the $substring() function/parameter to extract only the piece of text we need for that side and of course, as mentioned above, followed by a RETURN command in each case, to exit the DEFINE properly:

 

if($comparison($change text casing($substring(#var_Wing, 0, 1), "Upper Case"), "=", "L")) {
 then {
	 set(#var_Left_Wing_TEXT, $substring(#var_TEXT, 0, #var_Left_Wing_Length), "Local")
	 return(#var_Left_Wing_TEXT)
 }
 else {
	 set(#var_Right_Wing_TEXT, $substring(#var_TEXT, #var_Separator_End_Position, #var_Right_Wing_Length), "Local")
	 return(#var_Right_Wing_TEXT)
 }
}

 

Finally, here is a piece of code that will test the above function so you can see how it works in the DEBUGGER:

 

loop(1) {
set(#var_TEXT, "I code in UBot Studio daily and I'm happy!", "Global")
set(#var_TEST_ChooseLeft, $ChooseWing(#var_TEXT, "UBot ", "L"), "Global")
set(#var_TEST_ChooseRight, $ChooseWing(#var_TEXT, "UBot ", "R"), "Global")
}

 

The whole code of the DEFINE Function is below:

 

define $ChooseWing(#var_TEXT, #var_Separator, #var_Wing) {
set(#var_String_Length, $text length(#var_TEXT), "Local")
set(#var_Left_Wing_Length, $find index(#var_TEXT, #var_Separator), "Local")
set(#var_Separator_Length, $text length(#var_Separator), "Local")
set(#var_Separator_End_Position, $add(#var_Left_Wing_Length, #var_Separator_Length), "Local")
set(#var_Right_Wing_Length, $subtract(#var_String_Length, #var_Separator_End_Position), "Local")
divider
if($comparison($change text casing($substring(#var_Wing, 0, 1), "Upper Case"), "=", "L")) {
 then {
	 set(#var_Left_Wing_TEXT, $substring(#var_TEXT, 0, #var_Left_Wing_Length), "Local")
	 return(#var_Left_Wing_TEXT)
 }
 else {
	 set(#var_Right_Wing_TEXT, $substring(#var_TEXT, #var_Separator_End_Position, #var_Right_Wing_Length), "Local")
	 return(#var_Right_Wing_TEXT)
 }
}
}

 

I am also attaching the UBot Studio .ubot file to this as well, for people with STD Version only who cannot see the Code window.

 

Enjoy!

STRING-Left-Right-Wings-of-Text-Functions.ubot

  • Like 4
Link to post
Share on other sites

Why not just leave it at GLOBAL ?

 

Because it is a Custom Function that maybe you want to re-use elsewhere in the code, OR you want to use in multi-threading bots, etc...

 

In these cases you want to keep the temporary variables and their values confined within the 'capsule' of the subroutine/function you defined.

After all, you only need the result returned by the function's execution not all the intermediary values.

Link to post
Share on other sites
  • 2 weeks later...

if i understand this right , then couldn't the same code be modded to lets say cut down the length of the text, ie a list lets say and i want to cut its chars down to 80 chars for screen size, is it possible with this type idea?

 

ie sample text copy

 

Just when I thought hockey was getting bigger here.they have to do a walk out and now there wont be any hockey till at least next spring at this rate and they all still get paid the same i mean WTF

 

its char count is 197 chars, could this be used to cut all items in a list to 80 chars to fit that screen automatically and then send it back to the main list container?

 

Just when I thought hockey was getting bigger here.they have to do a walk out and now there wont be any hockey till at least next spring

 

and would only be that line in the list item after which is 77 chars but fits in the 80 chars limit

 

do able?

 

so that no text over 80 chars will be in that list so they will all fit the screen size or post size

Link to post
Share on other sites

pretty much i need the function to cut a list items down to 80 chars max and strip off whatever is over that on the fly after the list is loaded from a file and cut and cleaned to 80 chars before being used to post to any forms etc.. if that helps give the idea

Link to post
Share on other sites

Yes, of course... why wouldn't it?

 

It is perfectly possible. Of course, the code needs to be a bit altered, as now it accepts some content as a separator, while you are seeking positioning directly, but it is very easy to do it, np...

Link to post
Share on other sites

care to give a learning example? im trying to make it scrape a web page to a list, then clean the list of any weird or stupid chars and cut it to 80 chars max so i can use the list items to use in forms

 

been messing with $replace but its not clear to me yet how to add all the available chars

 

i picked the common ones ie

 

@ # % ( ) { } [ ] \ | should be a good enough start for me to test it out not sure if there is an easier way that i havent discovered yet

Link to post
Share on other sites

This is the simple code to trim your list down to max 80 chars for each element:

 

add list to list(%lst_Loaded_from_File, $list from file("REPLACE-WITH-YOUR-FILE-PATH-HERE"), "Delete", "Global")
set(#var_CYC_List_Loop_Counter, 0, "Global")
set(#var_CYC_List_Total_Elements, $list total(%lst_Loaded_from_File), "Global")
loop while($comparison(#var_CYC_List_Loop_Counter, "<", #var_CYC_List_Total_Elements)) {
   set(#var_CRT_Current_List_Item, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter), "Global")
   set(#var_CRT_Current_List_Item, $trim(#var_CRT_Current_List_Item), "Global")
   if($comparison($text length(#var_CRT_Current_List_Item), ">", 80)) {
    then {
	    set(#var_CRT_Current_List_Item, $substring(#var_CRT_Current_List_Item, 0, 80), "Global")
    }
    else {
    }
   }
   remove from list(%lst_Loaded_from_File, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter))
   add item to list(%lst_Loaded_from_File, #var_CRT_Current_List_Item, "Don\'t Delete", "Global")
   increment(#var_CYC_List_Loop_Counter)
}

 

Note the IF command that makes sure you won't get errors when the length of the list item to be processed is less than your limit (80)...

 

If you want to replace certain characters inside each list item before trimming it, you should do so before the $trim function/parameter in the code.

That is a different topic though (replacing chars) - very particular to each case, etc...

 

The very very simplistic approach would be to sequentially replace each unwanted character, one after the other...

The more complex approach would be to write a REGEX to do it in one sweep

 

In both cases the code depends on the chosen chars, though...

 

The very simple example, removing only the '@' & the '#' characters would look like this:

 

add list to list(%lst_Loaded_from_File, $list from file("REPLACE-WITH-YOUR-FILE-PATH-HERE"), "Delete", "Global")
set(#var_CYC_List_Loop_Counter, 0, "Global")
set(#var_CYC_List_Total_Elements, $list total(%lst_Loaded_from_File), "Global")
loop while($comparison(#var_CYC_List_Loop_Counter, "<", #var_CYC_List_Total_Elements)) {
   set(#var_CRT_Current_List_Item, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter), "Global")
   set(#var_CRT_Current_List_Item, $replace(#var_CRT_Current_List_Item, "@", $nothing), "Global")
   set(#var_CRT_Current_List_Item, $replace(#var_CRT_Current_List_Item, "#", $nothing), "Global")
   set(#var_CRT_Current_List_Item, $trim(#var_CRT_Current_List_Item), "Global")
   if($comparison($text length(#var_CRT_Current_List_Item), ">", 80)) {
    then {
	    set(#var_CRT_Current_List_Item, $substring(#var_CRT_Current_List_Item, 0, 80), "Global")
    }
    else {
    }
   }
   remove from list(%lst_Loaded_from_File, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter))
   add item to list(%lst_Loaded_from_File, #var_CRT_Current_List_Item, "Don\'t Delete", "Global")
   increment(#var_CYC_List_Loop_Counter)
}

 

...while the REGEX approach would rather look like this:

 

add list to list(%lst_Loaded_from_File, $list from file("REPLACE-WITH-YOUR-FILE-PATH-HERE"), "Delete", "Global")
set(#var_CYC_List_Loop_Counter, 0, "Global")
set(#var_CYC_List_Total_Elements, $list total(%lst_Loaded_from_File), "Global")
loop while($comparison(#var_CYC_List_Loop_Counter, "<", #var_CYC_List_Total_Elements)) {
   set(#var_CRT_Current_List_Item, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter), "Global")
   set(#var_CRT_Current_List_Item, $replace regular expression(#var_CRT_Current_List_Item, "(@|#)", $nothing), "Global")
   set(#var_CRT_Current_List_Item, $trim(#var_CRT_Current_List_Item), "Global")
   if($comparison($text length(#var_CRT_Current_List_Item), ">", 80)) {
    then {
	    set(#var_CRT_Current_List_Item, $substring(#var_CRT_Current_List_Item, 0, 80), "Global")
    }
    else {
    }
   }
   remove from list(%lst_Loaded_from_File, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter))
   add item to list(%lst_Loaded_from_File, #var_CRT_Current_List_Item, "Don\'t Delete", "Global")
   increment(#var_CYC_List_Loop_Counter)
}

 

Notice the use of pipe '|' for the alternate characters to be replaced, that is functioning pretty much like a logical OR.

 

HTH...

  • Like 1
Link to post
Share on other sites

The code above also deletes the processed list items when finished, followed by adding them at the end of the same list.

Basically, this way you will get the list properly trimmed after looping it all.

You can then save it to disk or whatever...

 

However, if you want to keep the original list intact, you need to edit the code and:

  1. delete the REMOVE FROM LIST command there as well as
  2. edit the ADD ITEM TO LIST command which now instead of adding the element to the same list should add to a new list that you will name accordingly... say: %lst_List_Trimmed (or anything you like better)

Cheers!

  • Like 1
Link to post
Share on other sites

great stuff thank you

 

one thing tho it keeps giving me an error on

 

Conversion from string "adds some text from the file list" to type "integer is not valid

 

source loop while > remove from list

 

did i miss something i had to change other then the file name for the list import?

Link to post
Share on other sites

if i bypass the errors with continue it does trim the text, i modded it so it goes to a second list in the second last line of the regex code , so i can see it clearer but its working except for that Integer error popup on run

 

any ideas?

Link to post
Share on other sites

did i miss something i had to change other then the file name for the list import?

 

Don't just paste the file location there directly in CODE View if you don't know exactly how to escape characters, but rather navigate to your file in Node View, so that UBot automatically adds the correct file path in the command.

 

Probably, your path now looks something like...

 

D:\My Documents\UBots Bots\myfile.txt

 

When in fact, in CODE View mode, should rather look like:

 

D:\\My Documents\\UBots Bots\\myfile.txt
  • Like 1
Link to post
Share on other sites

one thing tho it keeps giving me an error on

 

Conversion from string "adds some text from the file list" to type "integer is not valid

 

source loop while > remove from list

 

If you can't make it work, paste your code here so I can take a look...

Link to post
Share on other sites

add list to list(%lst_Loaded_from_File, $list from file("U:\\new stuff\\NHL\\nhl lockout.txt"), "Delete", "Global")
set(#var_CYC_List_Loop_Counter, 0, "Global")
set(#var_CYC_List_Total_Elements, $list total(%lst_Loaded_from_File), "Global")
loop while($comparison(#var_CYC_List_Loop_Counter, "<", #var_CYC_List_Total_Elements)) {
set(#var_CRT_Current_List_Item, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter), "Global")
set(#var_CRT_Current_List_Item, $replace regular expression(#var_CRT_Current_List_Item, "(@|#)", $nothing), "Global")
set(#var_CRT_Current_List_Item, $trim(#var_CRT_Current_List_Item), "Global")
if($comparison($text length(#var_CRT_Current_List_Item), ">", 80)) {
 then {
	 set(#var_CRT_Current_List_Item, $substring(#var_CRT_Current_List_Item, 0, 80), "Global")
 }
 else {
 }
}
remove from list(%lst_Loaded_from_File, $list item(%lst_Loaded_from_File, #var_CYC_List_Loop_Counter))
add item to list(%lst_Loaded_from_File2, #var_CRT_Current_List_Item, "Don\'t Delete", "Global")
increment(#var_CYC_List_Loop_Counter)
}

 

and here is the sample text

If I have to wait till November w/o NHL fine. Anything longer, Kill Me. #FireBettman
I am seriously gonna die without the NHL.
I'm seriously going to go crazy without the NHL.
If there's an NHL lockout, we riot!
Good thing for you there is a NHL lockout @JoeyMikos Rangers are going to be NASHTY this season,
NHL lockout is bullshit  I want my season tickets
For every game the @NHL cancels the fans should stay away for when they come back. #getitdone #emptyrinks
im gonna try and play nhl to live out this hockey season!!!!
Did I just hear that there's an #NHL? Again? Did they recover from the last one? #fb
Very disappointed with NHL lockout.  Both sides need to wake up and get things solved before fans take up new interest.
NHL lockout? Now what am I supposed to do? Take up knitting? #AsIf #MakeADealAlready
So do the @NHL_Oilers get first pick again in the draft again this year then?! #lockoutsilverlining #draftdynasty
@Proteautype thank you. hopefully we can still find some non NHL Hockey to watch in Vancouver!
If you are a @TheAHL season ticket holder, good for you! Schenn, Nugent-Hopkins, Couturier, Eberle etc …. all scheduled to play. #NHL
@HockeyRodent have to agree. cancelled my nhl center ice. i will not purchase anything with NHL on it
fuck this nhl lockout
Wait so when does the @NHL pre-season start again?? @ericgovs
I find this whole NHL thing to be annoying and gay #getittogether
i'm so sad that there's a NHL lockout
@CoachsCornerCBC Imagine what the NHLPA would say if replacement players were brought in for an NHL season. Same shite, different pile
I bet locked out NHL players regret spending all their money on Louis Vuitton and gold chains right about now.
So many NHL players are going to playing for teams whose names I can't pronounce.
Cheap tickets and news for the NHL is following me... I DON'T CARE ABOUT THE NHL!!!!! #SorryNotSorry
I think I played with the next NHL star!
Nobody knows why the always make Zdeno Chara so unrealistically big in all the NHL games....
Nothing else to do tonight. NHL for the night
Getting sick of the #NHL player tweets trying to win me over and hate the league..You have NO pity from me #livingthedream #youretheemployee
Send the displaced European players here to the NHL let the european team owners keep the overpaid scabbing douchebags .
Dear poor sad multi-millionaries @NHL @NHLPA we R in the midst of a global freakin recession! be happy with what you have! some have nothng
NHL lockout just means that all the teams are missing the playoffs, not just the Leafs #brightside
Nhl lockout =(
@MikeKHansen They'll all go back to the NHL. Exception is Swedish Elite League who won't take players on short term.
Holy fuck NHL moments is going to be the end of me #Rattled
@jessespector @realDonaldTrump @NHL isn't it speculators like Trump that have driven the gas prices up?
The NHL lockout is depriving us of Kevin Weekes hockey commentary.. #cbc #hnic
NHL lockout.... I can't.
Realizing that the one plus side to an NHL lockout as that we don't have to listen to Don Cherry #BrightSide
“@EmilieClarke: Mini baby boom because of the #NHL lockout? I think so!†LOL
#shitnoonesays I'm so glad theres an NHL lockout this year
WoW NHL has a lockout.. That sucks.. I swear Commish have sucked lately in every sport!

Link to post
Share on other sites

My bad, I wrote the code too quickly and didn't notice it first.

 

Change the line that removes the already trimmed list element into this:

   remove from list(%lst_Loaded_from_File, $list position(%lst_Loaded_from_File))

 

Also, note that IF you add the modified element to a new list rather than at the end of the same list, you will have to either:

  • delete (from the code) the removing from the initial list command, or else you will scan only half the list then get an error of exceeding list length
  • or, alternatively, along with removing it, shorten the max looping counter to address the new (shorter) list length after each removal, with a DECREMENT command for the variable: #var_CYC_List_Total_Elements

  • Like 1
Link to post
Share on other sites

My bad, I wrote the code too quickly and didn't notice it first.

 

Change the line that removes the already trimmed list element into this:

remove from list(%lst_Loaded_from_File, $list position(%lst_Loaded_from_File))

 

Also, note that IF you add the modified element to a new list rather than at the end of the same list, you will have to either:

  • delete (from the code) the removing from the initial list command, or else you will scan only half the list then get an error of exceeding list length
  • or, alternatively, along with removing it, shorten the max looping counter to address the new (shorter) list length after each removal, with a DECREMENT command for the variable: #var_CYC_List_Total_Elements

 

 

haha ok you sort of lost me on that last part can you explain? must be tired LOL

Link to post
Share on other sites

ok i see what you did there now, so it adds at the end of the list and then deletes the lines that (raw lines ) there first.

 

ya now work no error, could a duplicate remove be added in the cycle? or that would need different eval calculations right?

Link to post
Share on other sites

Yep, would complicate things, as you would have no control when that would happen, so you should re-calculate the max list length in each loop again and again, not just once...

 

Easiest way to do that would be to add the end resulting list (after being built with no dupe removal) to itself, WITH dupe removal in one single step.

Link to post
Share on other sites

BTW...

I keep telling people on various forums... when you like someone's help/contribution, expressing it is always very much appreciated (Thank you!) but hitting the LIKE THIS button of the post you liked helps a lot too... ;)

Link to post
Share on other sites

BTW...

I keep telling people on various forums... when you like someone's help/contribution, expressing it is always very much appreciated (Thank you!) but hitting the LIKE THIS button of the post you liked helps a lot too... ;)

 

HAHA

 

[b]	An error occurred[/b]

You have reached your quota of positive votes for the day

 

all for you bro ;-)

 

now how would i change this to be done on the fly lets say i scrape into a list and then process this with the code we got now... simple or?

Link to post
Share on other sites

HAHA

 

[b]	An error occurred[/b]

You have reached your quota of positive votes for the day

 

Ha, Ha, Ha... now is that cool, or what?

 

Thanks mate!

Link to post
Share on other sites

now how would i change this to be done on the fly lets say i scrape into a list and then process this with the code we got now... simple or?

 

Sure, just replace the part that loads the list from disk with the scraping you want done.

Make sure to save the scraped results into the list.

 

If you scrape attribute, it's directly done, but if you scrape table, then you would still have to save to disk and reload into a list (the simplest and quickest way) or else, to loop through the table instead of the list and apply a similar code, just this time you will have table cells, not list items...

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...