Testing Keyboards

13

1

My Problem

At my current place of employment, I single-handedly (ok dual-handedly because I'm missing no limbs) maintain approximately 700 laptops. Due to the nature and frequency of their use, I often find they are returned with a bit of damage. For this problem, my primary concern is when a laptop is returned with a broken or defunct keyboard. When the hardware repairman fixes these broken keyboards, it becomes necessary to test them. The test involves using each...and...every...single...key. What a drag right? The problem is, sometimes I lose track of if I typed a key or not.

A solution?

Write a program/script that:

  1. Takes user input
  2. Upon submission (in whatever way you deem fit), determines whether each key was pressed.
  3. Outputs yes or no or any way to indicate that either I was successful in pressing all the keys or not. (Indicate in your answer the two possible outputs if it's not something obvious).

Assumptions:

  1. Uppercase, lowercase, both? Whichever way you deem fit. As long as it's [A-Z], [a-z] or [A-Za-z]. Same goes with numbers and other symbols. (So if = was typed in, + doesn't matter). Your choice if you want to include shifted characters or not.
  2. You needn't worry about tabs or spaces
  3. No needs for function keys, CTRL, ALT, Esc or any other keys that don't output something on the screen
  4. This assumes an EN-US keyboard and the laptops do not include a numpad.
  5. OS agnostic, whatever language you prefer
  6. It doesn't matter if the key has been pressed multiple times (for when the tester just gets lazy and starts button smashing like it's Mortal Kombat)

Here's a potential input set that would return true (or yes, or "You did it!")

`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./

Winner is determined by the least number of characters.

SomeShinyObject

Posted 2014-06-07T13:38:40.063

Reputation: 953

Do we need to check that each keystroke appears at least once or exactly once? – xnor – 2014-06-07T14:04:11.480

@xnor, If it appears multiple times, it's ok. I updated the question. – SomeShinyObject – 2014-06-07T14:10:27.593

Are we allowed to use external libraries? – nyuszika7h – 2014-06-07T15:10:00.337

@nyuszika7h, yes but it counts toward the total # of chars. – SomeShinyObject – 2014-06-07T15:15:33.780

1Okay then, that isn't worth it. – nyuszika7h – 2014-06-07T15:34:56.793

1

@ChristopherW If this is an ongoing issue for you, you should have a look at this website http://www.keyboardtester.com/.

– gxtaillon – 2014-06-07T15:39:41.850

2@MomemtumMori, that hand doing the Pennsylvania Dutch keyboarding technique over in the side bar? Totally mine. – SomeShinyObject – 2014-06-07T15:44:07.313

Can we assume that the input contains only valid characters? – Dennis – 2014-06-07T18:35:30.957

@Dennis, yes you can. – SomeShinyObject – 2014-06-08T21:58:03.863

A quick note: it IS possible that a keyboard can type a lowercase of a certain letter, but doesn't work if you type that same letter with shift. I recently had to replace my keyboard after it failed to recognise uppercase S when I used the shift key. It recognized any lowercase letter, including s, and all uppercase letters excluding S, and it worked using caps-lock. I tested this on both a Mac and a PC, and I even wrote my own keylogger to verify this (which also incidentally unveiled another bug in my keyboard with my F12 key). So yes, you should really test both upper and lowercase. – Nzall – 2014-06-18T10:07:30.447

Answers

1

GolfScript, 6 bytes

.&,94=

If all ASCII characters with codes between 33 and 127 are present, it prints 1. Otherwise, it prints 0.

This approach will fail if the input contains other characters (including a final newline), which has been allowed by the OP and is also true for the existing GolfScript solution.

Usage

$ echo -n '!"#$%&'"'"'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' |
> golfscript <(echo '.&,94=')
1

How it works

.&  # Compute the intersection of the input string with itself. This removes duplicates.
,   # Compute the length of the resulting string.
94= # Push 1 if the length is 94, otherwise push 0.

Dennis

Posted 2014-06-07T13:38:40.063

Reputation: 196 637

The comment you linked doesn't say the input won't contain a newline (or other characters outside of 33-126), it just says it will only contain valid characters. Is newline an invalid character? – aditsu quit because SE is EVIL – 2014-06-10T11:29:49.770

By valid I meant in the range we're testing against, but I guess I should have expressed myself more clearly when asking the OP... – Dennis – 2014-06-10T13:49:31.340

6

GolfScript, 11

Printable ASCII isn’t that interesting…

127,32,-^,!

Ruby, 68

With flag -rset for 4 characters.

p Set.new(?`..?z)+(?,..?9)+%w{[ ] \\ ; '}==Set.new(gets.split'')

and

Python 3, 76

print(set("`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./")==set(input()))

Ry-

Posted 2014-06-07T13:38:40.063

Reputation: 5 283

1I'd suggest posting these in two separate answers. – nyuszika7h – 2014-06-07T15:42:42.523

3

JavaScript - 62 70

alert(!(47-prompt().match(/([',-\/\d;=a-z\[-\]`]?)(?!.*\1)/g).length))

And a bit shorter:

alert(!!prompt().match(/([',-\/\d;=a-z\[-\]`])(?!.*\1)/g)[46])

core1024

Posted 2014-06-07T13:38:40.063

Reputation: 1 811

2

CJam - 9

',33>q-!

It checks for the "shifted" characters too (including uppercase letters).
Try it at http://cjam.aditsu.net/

Note: there is an invisible character (with code 127) after the apostrophe.

aditsu quit because SE is EVIL

Posted 2014-06-07T13:38:40.063

Reputation: 22 326

“It checks for the "shifted" characters too (including uppercase letters).” I’d say that’s incorrect behaviour. – Ry- – 2014-06-07T15:48:13.670

@minitech "Your choice if you want to include shifted characters or not." – aditsu quit because SE is EVIL – 2014-06-07T15:49:27.850

But right before that, it says “Uppercase OR lowercase” (that’s exclusive, right?) – Ry- – 2014-06-07T15:51:02.137

@minitech, I updated the question. Sorry. That OR is misleading. – SomeShinyObject – 2014-06-07T15:54:14.977

@ChristopherW My program will print 0 on your example input, but if you also press all those characters while holding shift, it will print 1. Is that ok? – aditsu quit because SE is EVIL – 2014-06-07T15:59:33.327

@ChristopherW: So I just have to compare it against the set of printable ASCII? =/ – Ry- – 2014-06-07T16:04:45.230

@minitech, I should have made this a popularity contest. – SomeShinyObject – 2014-06-08T14:41:47.973

@aditsu, as long as it can confirm all the keys have been used, I'm ok. – SomeShinyObject – 2014-06-08T14:42:32.150

2

PHP

    foreach (str_split("`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./") as $v) {
        if (strpos($_GET['i'],$v)!==false)die(NO);
    }

$_GET['i'] is the input

Alireza Fallah

Posted 2014-06-07T13:38:40.063

Reputation: 151

1Use $_GET to save 1 char if it's acceptable. – tomsmeding – 2014-06-08T22:53:40.973

@tomsmeding, yeah I did :) – Alireza Fallah – 2014-06-09T04:35:20.660

You can add a padding character (é or something) to the front of your string and remove the !==false to save 8 characters, then the braces for 4 more. register_globals makes this "é$i". die(NO) is also possible. – Ry- – 2014-06-10T03:24:36.803

@minitech - I dont know what you say, padding character ? feel free to edit my answer instead – Alireza Fallah – 2014-06-10T04:46:00.123

1

Python 72:

f=lambda x:set(x)==set("`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./")

ɐɔıʇǝɥʇuʎs

Posted 2014-06-07T13:38:40.063

Reputation: 4 449

3The OP asked for a program that takes user input. – nyuszika7h – 2014-06-07T15:43:12.400

1

Haskell, 41 (two solutions)

interact(\y->show$all(`elem`y)[' '..'`'])

or (point-free style)

interact$show.(`all`[' '..'`']).flip elem

Need to input at least these characters:

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`

in any order, any number of times. Extra characters are allowed. Run in an interpreter. Must hit Enter when you are done, but if you hit Enter before you are done, you can keep entering characters, and press Enter again. Will print True if you have hit every character, otherwise it won't print anything.

YawarRaza7349

Posted 2014-06-07T13:38:40.063

Reputation: 71

0

Perl, 70 characters

say[sort grep!$s{$_}++,<>=~/\S/g]~~[sort"',-./;=[\]`"=~/./g,0..9,a..z]

Usage:

echo `134223423567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./ | perl -E 'say[sort grep!$s{$_}++,pop=~/\S/g]~~[sort"',-./;=[\]`"=~/./g,0..9,a..z]'

Prints 1 if all keystrokes present, else prints nothing.

Zaid

Posted 2014-06-07T13:38:40.063

Reputation: 1 015

Requires Perl 5.10+ – Zaid – 2014-06-08T18:25:10.963

In most shells, your example will fail since some of the characters in the echoed string require escaping. – Dennis – 2014-06-09T21:27:10.627

0

C, 97 characters

main(long a,char**u){a=0xfb0000000750003d;for(u++;**u;a|=2L<<*(*u)++-39);a=48+!~a;write(1,&a,1);}

Need to call the program with argument containing at least the letters:

`1234567890-=AZERTYUIOPQSDFGHJKLMWXCVBN[]\;',./

and get answer 1 (true). The charset can be changed by changing the initialization value of a.

Franzzzzzzzz

Posted 2014-06-07T13:38:40.063

Reputation: 1