Got a bit confused whilst testing something at work as one of the luhn validation tools at work decided to change it's mind around what the check digit should be, I wrote my own:
Luhn algorithm
package com.company;
public class luhnValidator {
public boolean isValidLuhn(String inputNumber) {
int[] numbers = stringToIntArray(inputNumber);
specialDoubler(numbers);
int total = sumIntArray(numbers);
return (total * 9) % 10 == numbers[numbers.length-1] ;
}
public int checkDigitCalc(String numberWithNoCheckDigit) {
int[] numbers = stringToIntArray(numberWithNoCheckDigit);
specialDoubler(numbers);
int total = sumIntArray(numbers);
return (total * 9) % 10;
}
private int[] stringToIntArray(String convertToNumbers) {
char[] brokenToChars = convertToNumbers.toCharArray();
int[] numbers = new int[brokenToChars.length];
for (int i = 0; i < brokenToChars.length; i++) {
numbers[i] = Character.getNumericValue(brokenToChars[i]) ;
}
return numbers;
}
/**
* Double every second number if greater than 10 add the products together
*/
private void specialDoubler(int[] numbers) {
int x2;
for (int i = numbers.length-2; i >= 0; i -= 2) {
x2 = numbers[i] * 2;
if (x2 < 10) {
numbers[i] = x2;
} else {
numbers[i] = (x2 - 10) + 1;
}
}
}
private int sumIntArray(int[] numbers) {
int total = 0;
for (int i = 0; i < numbers.length-1; i++ ) {
total += numbers[i];
}
return total;
}
}
Could still be optimised but it was fun to play with the intellij tests for jUnit, as they did help pick out a simple error where I missed out the '>' in >=.
Sunday, 20 December 2015
More links
https://www.ifixit.com/ actually looks handy and has my phone on there with a guide to replace the battery.
Article I liked http://allankelly.blogspot.co.uk/2015/10/software-has-diseconomies-of-scale-not.html
And a website I liked, seems simple enough and they accept bitcoin https://www.braintreepayments.com/
Article I liked http://allankelly.blogspot.co.uk/2015/10/software-has-diseconomies-of-scale-not.html
And a website I liked, seems simple enough and they accept bitcoin https://www.braintreepayments.com/
Wednesday, 16 December 2015
Quick challenge
Quick challenge after work, avoiding putting a front end on the lego app sigh.
package com.company;
import java.util.ArrayList;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String inputText = "The legend, propagated by email and message boards, purportedly demonstrates that readers can understand the "
+ "meaning of words in a sentence even when the interior letters of each word are scrambled. As long as all the necessary letters "
+ "are present, and the first and last letters remain the same, readers appear to have little trouble reading the text.";
String aPattern = "\\w+";
Pattern pattern = Pattern.compile(aPattern);
Matcher matcher = pattern.matcher(inputText);
ArrayList<String> words = new ArrayList<>();
while (matcher.find()) {
words.add(matcher.group());
}
StringBuilder outputWords = new StringBuilder(inputText.length());
String shuffledWord, middle;
char firstLetter, lastLetter;
for (String word : words) {
if(word.length() > 3) {
//build messed up words keeping edges same
firstLetter = word.charAt(0);
lastLetter = word.charAt(word.length()-1);
middle = wordShuffler(word.substring(1, word.length() - 1));
shuffledWord = firstLetter + middle + lastLetter;
} else {
shuffledWord = word;
}
outputWords.append(shuffledWord);
}
String nonWord = "\\W+";
pattern = Pattern.compile(nonWord);
matcher = pattern.matcher(inputText);
while (matcher.find()) {
outputWords.insert(matcher.start(), matcher.group());
}
System.out.println(inputText);
System.out.println(outputWords);
}
public static String wordShuffler(String wordToShuffle) {
char[] letterArray = wordToShuffle.toCharArray();
Random random = new Random();
int nextValue;
char swap;
for (int i = 0; i < letterArray.length; i++) {
swap = letterArray[i];
nextValue = random.nextInt(letterArray.length);
letterArray[i] = letterArray[nextValue];
letterArray[nextValue] = swap;
}
return new String(letterArray);
}
}
package com.company;
import java.util.ArrayList;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String inputText = "The legend, propagated by email and message boards, purportedly demonstrates that readers can understand the "
+ "meaning of words in a sentence even when the interior letters of each word are scrambled. As long as all the necessary letters "
+ "are present, and the first and last letters remain the same, readers appear to have little trouble reading the text.";
String aPattern = "\\w+";
Pattern pattern = Pattern.compile(aPattern);
Matcher matcher = pattern.matcher(inputText);
ArrayList<String> words = new ArrayList<>();
while (matcher.find()) {
words.add(matcher.group());
}
StringBuilder outputWords = new StringBuilder(inputText.length());
String shuffledWord, middle;
char firstLetter, lastLetter;
for (String word : words) {
if(word.length() > 3) {
//build messed up words keeping edges same
firstLetter = word.charAt(0);
lastLetter = word.charAt(word.length()-1);
middle = wordShuffler(word.substring(1, word.length() - 1));
shuffledWord = firstLetter + middle + lastLetter;
} else {
shuffledWord = word;
}
outputWords.append(shuffledWord);
}
String nonWord = "\\W+";
pattern = Pattern.compile(nonWord);
matcher = pattern.matcher(inputText);
while (matcher.find()) {
outputWords.insert(matcher.start(), matcher.group());
}
System.out.println(inputText);
System.out.println(outputWords);
}
public static String wordShuffler(String wordToShuffle) {
char[] letterArray = wordToShuffle.toCharArray();
Random random = new Random();
int nextValue;
char swap;
for (int i = 0; i < letterArray.length; i++) {
swap = letterArray[i];
nextValue = random.nextInt(letterArray.length);
letterArray[i] = letterArray[nextValue];
letterArray[nextValue] = swap;
}
return new String(letterArray);
}
}
Sunday, 13 December 2015
yousician
Actually impressed by an app, yousician, it actually looks good, I always wanted to learn to play then becoming an adult all the teachers only want to teach dam kids. Never mind :).
Pleased with the lego app, I got some more tests running and talking to people about should tests be run only the public methods or the private ones using reflection.
Pleased with the lego app, I got some more tests running and talking to people about should tests be run only the public methods or the private ones using reflection.
Sunday, 6 December 2015
Books and colours
Book I've been reading, Icarus deception by Seth Godin, enjoyed it, about making art is not comfortable and makes us feel vulnerable which is how you know you're making something new. I did like that Icarus could also fly too low.
Article I found interesting, Crash only software.
Sit stand desk, stand desks are normally so expensive but this looks good for the cost, varidesk.
12 years in software development article.
Been playing with a Lego picture maker and trying to get rgb values from Lego colours, after doing an average of the rgb values and using the closest average made a lot of thing purple. Delta-E 1976, fast enough with results accurate enough for what I want. My implementation, more info on it.
public static int[] getLegoColourEquiv(int[] rgb) {
int[] returnColourRGB = {1,1,1};
if(rgb == null) {
return returnColourRGB;
}
double lowestDelta = Double.MAX_VALUE;
double deltaE;
for (int[] colour : colours) {
//DeltaE76 (CIE 1976)
deltaE = Math.sqrt(
Math.pow(rgb[0] - colour[0], 2) +
Math.pow(rgb[1] - colour[1], 2) +
Math.pow(rgb[2] - colour[2], 2)
);
if(deltaE < lowestDelta) {
lowestDelta = deltaE;
returnColourRGB = Arrays.copyOf(colour,
colour.length);
}
}
return returnColourRGB;
}
Article I found interesting, Crash only software.
Sit stand desk, stand desks are normally so expensive but this looks good for the cost, varidesk.
12 years in software development article.
Been playing with a Lego picture maker and trying to get rgb values from Lego colours, after doing an average of the rgb values and using the closest average made a lot of thing purple. Delta-E 1976, fast enough with results accurate enough for what I want. My implementation, more info on it.
public static int[] getLegoColourEquiv(int[] rgb) {
int[] returnColourRGB = {1,1,1};
if(rgb == null) {
return returnColourRGB;
}
double lowestDelta = Double.MAX_VALUE;
double deltaE;
for (int[] colour : colours) {
//DeltaE76 (CIE 1976)
deltaE = Math.sqrt(
Math.pow(rgb[0] - colour[0], 2) +
Math.pow(rgb[1] - colour[1], 2) +
Math.pow(rgb[2] - colour[2], 2)
);
if(deltaE < lowestDelta) {
lowestDelta = deltaE;
returnColourRGB = Arrays.copyOf(colour,
colour.length);
}
}
return returnColourRGB;
}
Sunday, 22 November 2015
Update to lego thing as well
Link to MIT algorithms course, bought a book then omg this is hard.
Listening to podcasts https://codecombat.com/ came up, actually looks fun but bad memories of javascript under pressure.
I had another go at the lego picture maker, does seem to have a tendency to make the colours purple for some reason. Also IntStream just makes some of this stuff so easy.
Once it is in a better state I would like to get it on github. I get a bit hung up about poor code, I come back to it weeks later with wtf was I thinking. Need to add a front end, accept different input and output file types, and those actual lego nubs.
Must get away from magic numbers.
public static int[] getLegoColourEquiv(int[] rgb) {
int[] returnColourRGB = {1,2,3};
if(rgb == null) {
return returnColourRGB;
}
int rgbAverage = IntStream.of(rgb).sum() / rgb.length;
int gapFromColour = Integer.MAX_VALUE;
int colourAverage;
int rgbDiff;
for (int[] colour : colours) {
colourAverage = IntStream.of(colour).sum() / colour.length;
rgbDiff = rgbAverage - colourAverage ;
if(rgbDiff < 0) { rgbDiff *= -1;}
if(rgbDiff < gapFromColour) {
gapFromColour = rgbDiff;
returnColourRGB = Arrays.copyOf(colour, colour.length);
}
}
return returnColourRGB;
}
Listening to podcasts https://codecombat.com/ came up, actually looks fun but bad memories of javascript under pressure.
I had another go at the lego picture maker, does seem to have a tendency to make the colours purple for some reason. Also IntStream just makes some of this stuff so easy.
Once it is in a better state I would like to get it on github. I get a bit hung up about poor code, I come back to it weeks later with wtf was I thinking. Need to add a front end, accept different input and output file types, and those actual lego nubs.
Must get away from magic numbers.
public static int[] getLegoColourEquiv(int[] rgb) {
int[] returnColourRGB = {1,2,3};
if(rgb == null) {
return returnColourRGB;
}
int rgbAverage = IntStream.of(rgb).sum() / rgb.length;
int gapFromColour = Integer.MAX_VALUE;
int colourAverage;
int rgbDiff;
for (int[] colour : colours) {
colourAverage = IntStream.of(colour).sum() / colour.length;
rgbDiff = rgbAverage - colourAverage ;
if(rgbDiff < 0) { rgbDiff *= -1;}
if(rgbDiff < gapFromColour) {
gapFromColour = rgbDiff;
returnColourRGB = Arrays.copyOf(colour, colour.length);
}
}
return returnColourRGB;
}
Wednesday, 18 November 2015
Messy code which was fun to write
Some bits this week
cmd quser says when the user logged on, handy for when the boss asks why I am packing up so early, because I got here early :)
Found what looks like a good book, The Icarus Deception: How High Will You Fly?
rainforestQA awesome to have that many testers on standby.
Good pod cast, software engineering daily.
At the moment I like the idea of getting a laptop with a Linux on to play with even if it is dual boot.
So here is a mess but it works, trying to write a program that turns an image into lego blocks.
package com.company;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
public class LegoPictureMaker {
public String filePath;
public BufferedImage img;
public int legoSquareSideLength;
public LegoPictureMaker(String filePath) {
this.legoSquareSideLength = 16;
this.filePath = filePath;
}
public void makeImage() {
System.out.println("Grabbing file...");
img = grabFile();
System.out.println("Processing lego blocks");
processFile();
System.out.println("Done!");
}
//process file
private void processFile() {
//work out of squares needed in width and height
int xTiles = img.getRaster().getWidth() / legoSquareSideLength;
int yTiles = img.getRaster().getHeight() / legoSquareSideLength;
//build image I can write to
BufferedImage buildImage;
buildImage = new BufferedImage(
(xTiles * legoSquareSideLength),
(yTiles * legoSquareSideLength),
BufferedImage.TYPE_INT_RGB);
int totalTiles = xTiles * yTiles;
int red= 0, green = 0, blue = 0;
int[] testArray = new int[3];
img.getRaster().getPixel(0,0, testArray);
//make something usable
WritableRaster writableRaster = (WritableRaster)buildImage.getData();
int[][][] averageColour = new int[xTiles][yTiles][3];
for(int x = 0; x < xTiles; x++) {
for (int y = 0; y < yTiles; y++) {
averageColour[x][y] = getAverageColour(x * legoSquareSideLength, y * legoSquareSideLength);
writeTileColour(writableRaster, x * legoSquareSideLength, y * legoSquareSideLength, averageColour[x][y]);
}
}
saveImage(buildImage, writableRaster);
}
private void writeTileColour(WritableRaster writableRaster, int xPoint, int yPoint, int[] rgbValues) {
int endX = xPoint + legoSquareSideLength;
int endY = yPoint + legoSquareSideLength;
for (int x = xPoint; x < endX; x++) {
for (int y = yPoint; y < endY; y++) {
writableRaster.setPixel(x, y, rgbValues);
}
}
}
private int[] getAverageColour(int xPoint, int yPoint) {
int red= 0, green = 0, blue = 0;
int endX = xPoint + legoSquareSideLength;
int endY = yPoint + legoSquareSideLength;
int[] testArray = new int[3];;
for (int i = xPoint; i < endX; i++) {
for (int j = yPoint; j < endY; j++) {
img.getRaster().getPixel(i,j, testArray);
red += testArray[0];
green += testArray[1];
blue += testArray[2];
}
}
int amountOfPixels = legoSquareSideLength * legoSquareSideLength;
return new int[] { red / amountOfPixels,
green / amountOfPixels,
blue / amountOfPixels};
}
//save image
public void saveImage(BufferedImage buildImage, WritableRaster writableRaster) {
//save and close file
buildImage.setData(writableRaster);
File outputFile = new File("testest.png");
try {
ImageIO.write(buildImage, "png", outputFile);
} catch (IOException ex) {
ex.printStackTrace();
}
}
//get the file
public BufferedImage grabFile() {
BufferedImage img = null;
if (filePath != null && !filePath.isEmpty()) {
try {
img = ImageIO.read(new File(this.filePath));
} catch (IOException ex) {
System.out.println("broke here");
ex.printStackTrace();
}
}
return img;
}
}
cmd quser says when the user logged on, handy for when the boss asks why I am packing up so early, because I got here early :)
Found what looks like a good book, The Icarus Deception: How High Will You Fly?
rainforestQA awesome to have that many testers on standby.
Good pod cast, software engineering daily.
At the moment I like the idea of getting a laptop with a Linux on to play with even if it is dual boot.
So here is a mess but it works, trying to write a program that turns an image into lego blocks.
package com.company;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
public class LegoPictureMaker {
public String filePath;
public BufferedImage img;
public int legoSquareSideLength;
public LegoPictureMaker(String filePath) {
this.legoSquareSideLength = 16;
this.filePath = filePath;
}
public void makeImage() {
System.out.println("Grabbing file...");
img = grabFile();
System.out.println("Processing lego blocks");
processFile();
System.out.println("Done!");
}
//process file
private void processFile() {
//work out of squares needed in width and height
int xTiles = img.getRaster().getWidth() / legoSquareSideLength;
int yTiles = img.getRaster().getHeight() / legoSquareSideLength;
//build image I can write to
BufferedImage buildImage;
buildImage = new BufferedImage(
(xTiles * legoSquareSideLength),
(yTiles * legoSquareSideLength),
BufferedImage.TYPE_INT_RGB);
int totalTiles = xTiles * yTiles;
int red= 0, green = 0, blue = 0;
int[] testArray = new int[3];
img.getRaster().getPixel(0,0, testArray);
//make something usable
WritableRaster writableRaster = (WritableRaster)buildImage.getData();
int[][][] averageColour = new int[xTiles][yTiles][3];
for(int x = 0; x < xTiles; x++) {
for (int y = 0; y < yTiles; y++) {
averageColour[x][y] = getAverageColour(x * legoSquareSideLength, y * legoSquareSideLength);
writeTileColour(writableRaster, x * legoSquareSideLength, y * legoSquareSideLength, averageColour[x][y]);
}
}
saveImage(buildImage, writableRaster);
}
private void writeTileColour(WritableRaster writableRaster, int xPoint, int yPoint, int[] rgbValues) {
int endX = xPoint + legoSquareSideLength;
int endY = yPoint + legoSquareSideLength;
for (int x = xPoint; x < endX; x++) {
for (int y = yPoint; y < endY; y++) {
writableRaster.setPixel(x, y, rgbValues);
}
}
}
private int[] getAverageColour(int xPoint, int yPoint) {
int red= 0, green = 0, blue = 0;
int endX = xPoint + legoSquareSideLength;
int endY = yPoint + legoSquareSideLength;
int[] testArray = new int[3];;
for (int i = xPoint; i < endX; i++) {
for (int j = yPoint; j < endY; j++) {
img.getRaster().getPixel(i,j, testArray);
red += testArray[0];
green += testArray[1];
blue += testArray[2];
}
}
int amountOfPixels = legoSquareSideLength * legoSquareSideLength;
return new int[] { red / amountOfPixels,
green / amountOfPixels,
blue / amountOfPixels};
}
//save image
public void saveImage(BufferedImage buildImage, WritableRaster writableRaster) {
//save and close file
buildImage.setData(writableRaster);
File outputFile = new File("testest.png");
try {
ImageIO.write(buildImage, "png", outputFile);
} catch (IOException ex) {
ex.printStackTrace();
}
}
//get the file
public BufferedImage grabFile() {
BufferedImage img = null;
if (filePath != null && !filePath.isEmpty()) {
try {
img = ImageIO.read(new File(this.filePath));
} catch (IOException ex) {
System.out.println("broke here");
ex.printStackTrace();
}
}
return img;
}
}
Subscribe to:
Posts (Atom)