Arduino Setup

I’m coming back around to using the Arduino again after putting the project down a year ago (along with everything else due to health issues). I had great results last time and the code is in GitHub, but I’m starting from scratch in order to have deep familiarity going forward.

My preference is to work with Ruby because I like Ruby. I’ve got various environments I’m working with, one of which is a dual-boot box running Ubuntu 18.04. When I began the process of trying out gems for development, I started running through setup steps here: https://playground.arduino.cc/Interfacing/Ruby

When I came to the step where I needed to upload firmata, I got an error message, the heart of which was “avrdude: ser_open(): can’t open device “/dev/ttyACM0″: Permission denied.” When I googled that term + 18.04 for my Ubuntu install, I got the help I needed from this site: http://arduino-er.blogspot.com/2014/08/arduino-ide-error-avrdude-seropen-cant.html. There it states:

“To fix it, enter the command:
sudo usermod -a -G dialout <username>
sudo chmod a+rw /dev/ttyACM0
Where <username> is your user name in Ubuntu, /dev/ttyACM0 is the detected device of your Arduino board.”

The next time I uploaded, there was no error. If anyone else runs into this, I encourage you to try those same steps for 18.04. They worked for me.

Advertisements

Simplifying (multilinear non-constant polynomials) Polynomials with Ruby

Another CodeWars challenge I tackled in Ruby. The instructions were to take multilinear non-constant polynomials (that is, those with out degrees but with coefficients), and to simplify them. Such a problem would be:

-x – xy – yx +x -10z -10b

Should result in -10b – 10z + 2xy (as the x’s have cancelled each other, and the xy and yx variables are really the same). That’s not a bad example, because the instructions specify that the terms must be ordered first by the length of the variable set (the xy’s with their length of two letter should come after those with a single letter, like -10b and -10z). However, the ordering of the variables must be alphabetical. -xy and -yx combine to -2xy, because x comes before y. These were the instructions, and they were accomplished by the following code:


def simplify (poly)
answer = []
done = []
hash_done, terms = Hash.new(0)
poly.scan(/[\+\-]*[[:alnum:]]+/).each {|terms| terms; done << terms}
done.each do |term|
coefficient, charset,blank = term.partition(/[[:alpha:]]+/)
charset = charset.chars.sort!.join
coefficient = coefficient.concat "1" if /\A[-?\+?]\Z/.match coefficient or coefficient.empty?
hash_done[charset]=hash_done[charset] += coefficient.to_i
end

hash_done.reject! {|k,v|v==0}
done = hash_done.to_a
done = done.sort_by { |l| [l[0].length, l]}
done = done.each {|el| el[1] = el[1].to_s.tr!("1","") if el[1].abs == 1 ; el.reverse!; answer<<el.join}
answer=answer.join("+").gsub(/\+-/,"-")
end

Here’s the fully annotated code that explains each step in greater detail:

def simplify (poly)
answer = []
done = []
hash_done, terms = Hash.new(0)
#The following line scans the incoming string and, unless it is has a coefficient of 0,
#parses it by sign & coefficient & terms, and places it into an array named "done",
#the coefficient and sign both being optional.
#Terms with coefficient 0 aren't even placed into the array.
poly.scan(/[\+\-]*[[:alnum:]]+/).each {|terms| terms; done<<terms}
done.each do |term|
#break up the term into a coefficient and charset. Partitioning creates a third value which is of no use here
coefficient, charset,blank = term.partition(/[[:alpha:]]+/)
charset = charset.chars.sort!.join #sort newly created charset for final answer, and so no dupes appear in hash for same terms
#if the coefficient is simply +, -, or blank, this means the coefficient is technically 1. We'll add it now, and remove later
coefficient = coefficient.concat "1" if /\A[-?\+?]\Z/.match coefficient or coefficient.empty?
hash_done[charset]=hash_done[charset] += coefficient.to_i#this is the math that adss/subtracts the coefficient and stores in hash
end

hash_done.reject! {|k,v|v==0} #Remove all k/v pairs with a value of 0. They won't be part of the final answer
done = hash_done.to_a #the rest of the transformations will be manipulated within an array
done = done.sort_by { |l| [l[0].length, l]} #the assignment requires that the terms be sorted by length of charset first, then aplha
#Get rid of any multipliers of 1 by matching on the abs value of 1. If exists, strip the 1. Then flip the [char, digit] pair and join
done = done.each {|el| el[1] = el[1].to_s.tr!("1","") if el[1].abs == 1 ; el.reverse!; answer<<el.join}
#join every element in the array together into a string, but any +- combos that result should be simplified to just "-". Leading
#subtraction symbols will be left intact
answer=answer.join("+").gsub(/\+-/,"-")
end

JS: ternary operator and regex

I worked on another 7kyu JS problem today on CodeWars, and the solution ended up making use of the JS ternary operator. I never used the ternary in Java, but I have in Ruby and the one used in JS looks similar.

The simple exercise was to get a count of vowels in a given string. My solution was as follows:


function getCount(str) {
 var vowelsCount = 0;
 str.toLowerCase().match(/[aeiou]/g)!=null ? vowelsCount=str.toLowerCase().match(/[aeiou]/g).length : vowelsCount = 0 ;
 return vowelsCount;
}

I liked my solution as the ternary made it pretty trim. The breakdown of the guts of the function is as follows:

  1. Set the vowelsCount to a baseline of 0. This line, and the function def itself, were both supplied by codewars, so they were left “as-is”.
  2. Using the JS ternary, query whether the supplied string (that has been set to lower case) matches via regex on the class of characters defined in square brackets. The trailing g in the regex specifies to make this a global search. The character class defined is, as you will note, my vowel list. Since the string has been set to lower case prior to matching, my lower case vowels should all be found. If they are found, set the value of vowelsCount to the value returned by the Array.length method. Otherwise set vowelsCount to 0.
  3. Return the value.

This worked, but I had a chance to look at other solutions, and found this can be made more trim. One way would be to use “/gi” as the flags on my regex. I used the ‘g’, but the ‘i’ would specify case insensitive, making the .toLowerCase unnecessary. However I didn’t regret learning that string method. It could prove handy 🙂

Another way to trim it down would be to do a conditional return, as someone did in this manner:

function getCount(str) {
return (str.match(/[aeiou]/ig)||[]).length;
}

I tried something similar using the ternary, but came across a warning not to do so, though without explication.  Anyway, this second solution is more readable and just as effective.

JS: Sigma

Ok, it’s been awhile since I wrote anything, but I switched back to Rails learning after putting Ruby down for awhile, and in the interim took a JS class too. Now I’m starting to dig into JS a bit, and CodeWars is a great place to practice. Here is an 7kyu from CodeWars to help get me started:

======================================================================

“Your task is to write a function which returns the sum of following series upto nth term(parameter).

Series: 1 + 1/4 + 1/7 + 1/10 + 1/13 + 1/16 +…”

###Rules:

  • You need to round the answer upto 2 decimal places and return it as String.
  • If the given value is 0 then it should return 0.00
  • You will only be given Natural Numbers as arguments.

###Examples:

SeriesSum(1) => 1 = "1"
SeriesSum(2) => 1 + 1/4 = "1.25"
SeriesSum(5) => 1 + 1/4 + 1/7 + 1/10 + 1/13 = "1.57"

========================================================================

I took this to mean “for some value x, sum 1/x to the prior iteration, adding 3 to x for each value of x greater than 1.”

I’d gotten out of the habit of using for-loops due to my recent focus on Ruby. For-loops are permitted in Ruby, but the .each method with a code block is so handy (and other similar iterative methods) that I simply never use them anymore. The peril of being thrown off by 1 is always pitfall. Well, JS may not look much like Java, but the for loops are very similar, and so after a bit of research into syntax, coding up the basic concept, and then futzing around with my starting values, I produced the following code that passed all the supplied tests. It’s not genius, but it got the job done! So, for your amazement:

function SeriesSum(n)
{
 var den = 1; //This will be my denominator. It will start at 1 and increment by 3 at the end of the for loop.
 var sum = 0; //Define a value to be summed.
 for (var i = 0; i < n; i++){ //a standard for loop. The iterator 'i' will run up to n-1. If n is 0, the loop will be skipped.
 sum += (1/den);//Base case of n = 1 and i is at 0: "sum = 0 + 1/1," which is 1. i will iterate just once more and add 1/4 to sum.
 den += 3;
 }
 return (sum).toFixed(2);//Here we use the Math built-in object and call its "toFixed" method to report the decimal to 2 places.

}

And the terse, uncommented version:

function SeriesSum(n)
{
var den = 1;
var sum = 0;
for (var i = 0; i<n; i++){

sum += (1/den);
den += 3;
}
return (sum).toFixed(2);

} 

Longest substring

I’ve just completed another CodeWars task, this one having to do with string manipulation. The task was to find the longest palindrome within a string. The strings supplied for testing didn’t have spaces, and that might have caused me to alter my solution if they did, but I’m unsure of that.

At any rate, the task was to return the length of the longest palindrome substring within a string. That is, in the string:

tworacecars

The longest palindrome would be “racecar” since that is a substring that may be found both forward and backward within the string supplied, so the answer would be “7.” From many years ago, I’m familiar with the palindrome “rats live on no evil star” as a palindrome, and I used that one for my own testing since every word within the longer string reverses.

My first approach was as follows:

  1. Create a data structure that will encounter every substring
  2. Record every substring to an array.
  3. Sort the array by length
  4. Take the length of the array value at position [0], and that is the answer.

I did get this solution working, but when I refactored I realized that this was very inefficient. Since the size could be evaluated at runtime, there was no need to populate and sort arrays. Rather, the substrings could be tested for whether or not they were a palindrome (i.e. stringy_thingy == stringy_thingy.reverse), and, if so, take the length. If the length was longer than the previously recorded highest length, then simply replace.

At first I checked around to see if there was anything Ruby could already “know” about the substrings of a string, but since I didn’t turn anything up there, my solution was this:

  1. Create a data structure that encounters every substring.
  2. Evaluate if it is a palindrome (s==s.reverse)
  3. If true and s.length is greater than that of the last previously recorded “longest” length, store s.length in a temp variable.

That’s the code I’ve included below:


def longest_palindrome s
#your code here
last_length = 0

=begin
This solution considers a string for its subelements one subarray at a time. I've nested to "do" statements
that, on the outside layer, considers the string from position 0 and increments upward, shortening the string
subarray by one moving from left to right. The inside "do" is a "downto" that shortens the upper boundary that
will be considered by 1 each iteration downto the current value of the outside "do", so for a string of length 5:
pass 1: evaluate string elements [0..5]
pass 2: evaluate string elements [0..4]
...
pass 7: evaluate string elements [1..5]
pass 8: evaluate string elements [1..4]

and so on, until every adjancent set of characters has been evaluated.
=end

0.upto (s.size-1) do |goingup|
(s.size-1).downto goingup do |down|
eval = s[goingup..down]
#Here is the logic: if the current substring is the same forward and backward, evaluate its
#length and record it in last_length if it is greater than the current value of last_length.
if eval == eval.reverse and eval.length > last_length then last_length = eval.length end
end
end
last_length #return the value of the last greatest length
end 

Legacy post: Locating page elements in Selenium using XPATH and span text

This will be the last of these legacy posts. I blogged some years back about some difficulties I was having at the time finding elements in a mobile app I was testing. It demonstrates the kinds of problems I was trying to solve while testing with Selenium.

—————————————————-

Locating page elements in Selenium using XPATH and span text

A developer gave me a great tip last Friday to help find elements in Selenium2 using span text. Right now the mobile app has a lot of elments that have id’s that aren’t fixed and have been very difficult to locate using location methods other than xpath. Some of that xpath has been grossly long. However, some of the tricky one’s had sensible text between spans. These ended up being the accessible identifiers.

You can nudge the selenium2 page object model location method in the direction you want by using the @FindBy annotation. This is divided into a “how” part and a “using” part. The “how” method to use for these cases is How.XPATH, and the using is in the form described below:

@FindBy(how = How.XPATH, using = “//span[text()=’sometermrighthere $’]“)

That’s it. The span text has worked to identify the elements well enough for the automated suite.

Another legacy post: TestNG

Another extract in a series of reposts from an era when I was building a test framework using Java, Selenium, and TestNG.  It reflects my thought processes and research into building a test suite.

————————————————————————–

TestNG suites: creating a proper testing.xml file

So far as I know, there is only one way to run a suite of tests through TestNG, and that is using an XML file. This happens to be true whether you are using Eclipse or not. If you want to run tests through the TestNG Eclipse plugin, you navigate to Run Configurations… in the Eclipse interface (either through the top menu or rt-click context menus). There you can run tests by:

Class

Method

Groups

Package

Suite

I’ve experimented with class, method, and groups, but not package. Unlike the others, “suite” doesn’t work unless you have an xml file defined. Once you do, however,when you choose the browse button for Suites you can choose multiple testing.xml files, thereby allowing you to build a “suite of suites”. Very handy, but there’s a catch:unless you have explicitly written exclusions into your suites, any suite that includes tests that are represented in other suites will be run again. That is, if you have a test that is tagged as both “smoke, functional” and you run your smoke suite back to back with your functional suite, this test will be run twice. This means the overall execution time will be longer. The way around this is to create groups of groups and define them in their own files. Groups of groups are explained in section 5.2 of the TestNG documentation.

What got the xml file working for me was putting a testing.xml file (apparently the name of the file isn’t important) at the package level and running it. I had defined my groups in the xml file, but at first it didn’t seem to work. It would act like it was executing, but wouldn’t actually run any tests. This may in fact have been the case, as it seems you also need to specify in the classes within which those groups will be chosen. It makes sense, but it wasn’t apparent to me at first.

Below is a sample testing.xml file that is known to have a good structure. It defines a suite (Suite1), a list of groups to include (in this case just those tests designated “@Test (groups = {“smoke”}) ” in the test file. Importantly, it defines the “package.class_name” in the <class> tag. The <parameter> tags aren’t essential. They simply happened tobe useful for the test at hand and are included here to demonstrate how they are used in context of the overall structure.

 <?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Suite1" verbose="10" >

<parameter name = "remote_url" value="http://localhost:4444/wd/hub"/>

<parameter name = "browser_key" value = "1"/>

<test name="Mobile-ish Login SmokeTests">

<groups>

<run>

<include name="smoke" />

</run>

</groups>

<classes>

<class name="org.openqa.selenium.example.TestNGSuite_Mobile_Login_Tests"/>

</classes>

</test>

</suite>