Showing posts with label Computer Science Academic Tutors. Show all posts
Showing posts with label Computer Science Academic Tutors. Show all posts

Saturday, 3 September 2016

Java,Python And SML Programming Assignment Help

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class hw3 {
public static void hw4(String input, String output) throws IOException{
PrintStream myconsole=new PrintStream(new File(output));
System.setOut(myconsole);
BufferedReader in = new BufferedReader(new FileReader(input));
ArrayList stack = new ArrayList();
HashMap hm = new HashMap();
String line = in.readLine();
while(line!=null){
if(line.equals(“let”)) {
stack.add(0,parseLet(in,hm,myconsole));
}
else if(Character.isLetter(line.charAt(0))){
stack = parsePrimitive(line, stack, hm, myconsole);
}
else if(line.charAt(0)==’:’){
stack = parseBooleanOrError(line, stack, hm);
}
else{
myconsole.println(“Error command!”);
}
line = in.readLine();
}
in.close();
}
public static Object parseLet(BufferedReader in, HashMap hm_parent, PrintStream myconsole) throws IOException {
ArrayList stack_let = new ArrayList();
HashMap hm_let = new HashMap(hm_parent);
String line = in.readLine();
while(!line.equals(“end”)){
if(line.equals(“let”)) {
stack_let.add(0,parseLet(in,hm_let,myconsole));
}
else if(Character.isLetter(line.charAt(0))){
stack_let = parsePrimitive(line, stack_let, hm_let, myconsole);
}
else if(line.charAt(0)==’:’){
stack_let = parseBooleanOrError(line, stack_let, hm_let);
}
else{
myconsole.println(“Error command!”);
}
line = in.readLine();
}
return stack_let.get(0);
}
public static ArrayList parseBooleanOrError(String line, ArrayList stack, HashMap hm) {
if (line.startsWith(“:e”)){
stack.add(0, “:error:”);
}
else if (line.startsWith(“:t”)){
stack.add(0, “:true:”);
}
else if (line.startsWith(“:f”)){
stack.add(0, “:false:”);
}
return stack;
}
public static ArrayList doMul(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
stack.remove(0);
stack.remove(0);
Integer newTop = x*y;
stack.add(0, newTop.toString());
}
return stack;
}
public static ArrayList doSub(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
stack.remove(0);
stack.remove(0);
Integer newTop = x-y;
stack.add(0, newTop.toString());
}
return stack;
}
public static ArrayList doAdd(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“(.*)[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“(.*)[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
stack.remove(0);
stack.remove(0);
Integer newTop = x+y;
stack.add(0, newTop.toString());
}
return stack;
}
public static ArrayList parsePrimitive(String line, ArrayList stack, HashMap hm, PrintStream myconsole){
if (line.startsWith(“add”)){
stack = doAdd(stack,hm);
}
else if (line.startsWith(“sub”)){
stack = doSub(stack,hm);
}
else if (line.startsWith(“mul”)){
stack = doMul(stack,hm);
}
else if (line.startsWith(“div”)){
stack = doDiv(stack,hm);
}
else if (line.startsWith(“rem”)){
stack = doRem(stack, hm);
}
else if (line.startsWith(“pop”)){
stack = doPop(stack);
}
else if (line.startsWith(“push”)){
stack = doPush(stack, line);
}
else if (line.startsWith(“swap”)){
stack = doSwap(stack);
}
else if (line.startsWith(“neg”)){
stack = doNeg(stack,hm);
}
else if (line.startsWith(“quit”)){
doQuit(stack, myconsole);
}
else if (line.startsWith(“if”)) {
doIf(stack,hm);
}
else if (line.startsWith(“not”)) {
doNot(stack,hm);
}
else if (line.startsWith(“and”)) {
doAnd(stack,hm);
}
else if (line.startsWith(“or”)) {
doOr(stack,hm);
}
else if (line.startsWith(“equal”)) {
doEqual(stack,hm);
}
else if (line.startsWith(“lessThan”)) {
doLessThan(stack,hm);
}
else if (line.startsWith(“bind”)) {
doBind(stack,hm);
}
return stack;
}
public static void doQuit(ArrayList stack, PrintStream myconsole) {
for (int i = 0; i < stack.size(); i++){
String s = (String) stack.get(i);
myconsole.println(s.replace(“\””,””));
}
myconsole.close();
}
public static ArrayList doNeg(ArrayList stack, HashMap hm) {
if (stack.isEmpty()){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
int x;
String s0 = (String) stack.get(0);
if(s0.matches(“(.*)[0-9]+”)) x = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s0_1);
}
Integer newTop = -1*x;
stack.remove(0);
stack.add(0, newTop.toString());
}
return stack;
}
private static ArrayList doSwap(ArrayList stack) {
if (stack.size() < 2){
stack.add(0, “:error:”);
}
else{
String x = (String) stack.get(1);
String y = (String) stack.get(0);
stack.remove(0);
stack.remove(0);
stack.add(0, y);
stack.add(0, x);
}
return stack;
}
public static ArrayList doPush(ArrayList stack, String line) {
String getNum = line.substring(5);
if (getNum.charAt(0) == ‘-‘){
if (getNum.substring(1).equals(“0”)){
stack.add(“0”);
}
else if (getNum.substring(1).matches(“[0-9]+”)){
stack.add(0, getNum);
}
else{
stack.add(0, “:error:”);
}
}
else if (getNum.matches(“[0-9]+”)){
stack.add(0, getNum);
}
else if (getNum.matches(“^[a-zA-Z].*”)){
stack.add(0, getNum);
}
else if (getNum.matches(“^\”.+\”$”)){
stack.add(0, getNum);
}
else{
stack.add(0, “:error:”);
}
return stack;
}
public static ArrayList doPop(ArrayList stack) {
if (stack.size() < 1){
stack.add(0, “:error:”);
}
else{
stack.remove(0);
}
return stack;
}
public static ArrayList doRem(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
if (y == 0){
stack.add(0, “:error:”);
}
else{
stack.remove(0);
stack.remove(0);
Integer newTop = x%y;
stack.add(0, newTop.toString());
}
}
return stack;
}
public static ArrayList doDiv(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
if (y == 0){
stack.add(0, “:error:”);
}
else{
stack.remove(0);
stack.remove(0);
Integer newTop = x/y;
stack.add(0, newTop.toString());
}
}
return stack;
}
public static ArrayList doIf(ArrayList stack, HashMap hm) {
if (stack.size()<3){
stack.add(0, “:error:”);
}
else {
String s2 = (String) stack.get(2);
if(!s2.equals(“:true:”) && !s2.equals(“:false:”)) s2 = (String) hm.get(s2);
if (s2 != null && s2.equals(“:true:”)) {
stack.remove(2);
stack.remove(1);
}
else if (s2 != null && s2.equals(“:false:”)) {
stack.remove(2);
stack.remove(0);
}
else{
stack.add(0, “:error:”);
}
}
return stack;
}
public static ArrayList doNot(ArrayList stack, HashMap hm) {
if (stack.size()<1){
stack.add(0, “:error:”);
}
else {
String s0 = (String) stack.get(0);
if(!s0.equals(“:true:”) && !s0.equals(“:false:”)) s0 = (String) hm.get(s0);
if(s0 == null){
stack.add(0, “:error:”);
}
else if (s0.equals(“:true:”)) {
stack.remove(0);
stack.add(0, “:false:”);
}
else if (s0.equals(“:false:”)) {
stack.remove(0);
stack.add(0, “:true:”);
}
else{
stack.add(0, “:error:”);
}
}
return stack;
}
public static ArrayList doAnd(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else {
String s0 = (String) stack.get(0);
if(!s0.equals(“:true:”) && !s0.equals(“:false:”)) s0 = (String) hm.get(s0);
String s1 = (String) stack.get(1);
if(!s1.equals(“:true:”) && !s1.equals(“:false:”)) s1 = (String) hm.get(s1);
if(s0 == null || s1 == null) {
stack.add(0, “:error:”);
}
else if (s0.equals(“:false:”) && s1.equals(“:false:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:false:”);
}
else if (s0.equals(“:false:”) && s1.equals(“:true:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:false:”);
}
else if (s0.equals(“:true:”) && s1.equals(“:false:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:false:”);
}
else if (s0.equals(“:true:”) && s1.equals(“:true:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:true:”);
}
else{
stack.add(0, “:error:”);
}
}
return stack;
}
public static ArrayList doOr(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else {
String s0 = (String) stack.get(0);
if(!s0.equals(“:true:”) && !s0.equals(“:false:”)) s0 = (String) hm.get(s0);
String s1 = (String) stack.get(1);
if(!s1.equals(“:true:”) && !s1.equals(“:false:”)) s1 = (String) hm.get(s1);
if(s0 == null || s1 == null) {
stack.add(0, “:error:”);
}
else if (s0.equals(“:false:”) && s1.equals(“:false:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:false:”);
}
else if (s0.equals(“:false:”) && s1.equals(“:true:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:true:”);
}
else if (s0.equals(“:true:”) && s1.equals(“:false:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:true:”);
}
else if (s0.equals(“:true:”) && s1.equals(“:true:”)) {
stack.remove(0);
stack.remove(0);
stack.add(0, “:true:”);
}
else{
stack.add(0, “:error:”);
}
}
return stack;
}
public static ArrayList doEqual(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
stack.remove(0);
stack.remove(0);
if(x == y) stack.add(0, “:true:”);
else stack.add(0, “:false:”);
}
return stack;
}
public static ArrayList doLessThan(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else if (((String) stack.get(0)).charAt(0) == ‘:’ || ((String) stack.get(1)).charAt(0) == ‘:’){
stack.add(0, “:error:”);
}
else{
String s1 = (String) stack.get(1);
String s0 = (String) stack.get(0);
int x,y;
if(s1.matches(“[0-9]+”)) x = Integer.parseInt(s1);
else {
String s1_1 = (String) hm.get(s1);
if(s1_1 == null || !s1_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
x = Integer.parseInt(s1_1);
}
if(s0.matches(“[0-9]+”)) y = Integer.parseInt(s0);
else {
String s0_1 = (String) hm.get(s0);
if(s0_1 == null || !s0_1.matches(“[0-9]+”)) {
stack.add(0, “:error:”);
return stack;
}
y = Integer.parseInt(s0_1);
}
stack.remove(0);
stack.remove(0);
if(x < y) stack.add(0, “:true:”);
else stack.add(0, “:false:”);
}
return stack;
}
public static ArrayList doBind(ArrayList stack, HashMap hm) {
if (stack.size()<2){
stack.add(0, “:error:”);
}
else {
String s0 = (String) stack.get(0);
String s1 = (String) stack.get(1);
if(s1.matches(“^[a-zA-Z].*”) && !s0.equals(“:error:”)) {
stack.remove(0);
stack.remove(0);
Object o = hm.get(s0);
if(o!=null) hm.put(s1,o);
else hm.put(s1,s0);
stack.add(0, “:unit:”);
}
else {
stack.add(0, “:error:”);
}
}
return stack;
}
}
import re
fInput = 0
def hw3(input, output):
global fInput
fInput = open(input,’r’)
f = open(output,’w’)
stack = []
hm = {}
for line in fileRead():
if line.startswith(‘let’):
stack.insert(0,parseLet(fInput,hm,f))
elif line[0].isalpha():
parsePrimitive(line, stack, hm, f)
elif line[0] == ‘:’:
parseBooleanOrError(line, stack, hm)
fInput.close()
def fileRead():
for line in fInput:
yield line
def parseLet(input,hm_parent,f):
global fInput
stack_let = []
hm_let = {}
for line in fileRead():
if line.startswith(‘end’):
return stack_let[0]
elif line[0] == ‘let’:
stack.insert(0,parseLet(fInput,hm_let,f))
elif line[0].isalpha():
parsePrimitive(line, stack_let, hm_let, f)
elif line[0] == ‘:’:
parseBooleanOrError(line, stack_let, hm_let)
def parsePrimitive(line, stack, hm, f):
if line.startswith(‘add’):
doAdd(stack, hm)
elif line.startswith(‘sub’):
doSub(stack, hm)
elif line.startswith(‘mul’):
doMul(stack, hm)
elif line.startswith(‘div’):
doDiv(stack, hm)
elif line.startswith(‘rem’):
doRem(stack, hm)
elif line.startswith(‘pop’):
doPop(stack)
elif line.startswith(‘push’):
doPush(stack, line)
elif line.startswith(‘swap’):
doSwap(stack)
elif line.startswith(‘neg’):
doNeg(stack, hm)
elif line.startswith(‘quit’):
doQuit(stack, f)
elif line.startswith(‘if’):
doIf(stack, hm)
elif line.startswith(‘not’):
doNot(stack, hm)
elif line.startswith(‘and’):
doAnd(stack, hm)
elif line.startswith(‘or’):
doOr(stack, hm)
elif line.startswith(‘equal’):
doEqual(stack, hm)
elif line.startswith(‘lessThan’):
doLessThan(stack, hm)
elif line.startswith(‘bind’):
doBind(stack, hm)
def doAdd(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
stack.pop(0)
stack.pop(0)
newTop = x+y
return stack.insert(0, str(newTop))
else:
return stack.insert(0, ‘:error:’)
def doSub(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
stack.pop(0)
stack.pop(0)
newTop = x-y
return stack.insert(0, str(newTop))
else:
return stack.insert(0, ‘:error:’)
def doMul(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
stack.pop(0)
stack.pop(0)
newTop = x*y
return stack.insert(0, str(newTop))
else:
return stack.insert(0, ‘:error:’)
def doDiv(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
if y == 0:
return stack.insert(0, ‘:error:’)
stack.pop(0)
stack.pop(0)
newTop = x*y
return stack.insert(0, str(newTop))
else:
return stack.insert(0, ‘:error:’)
def doRem(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
if y == 0:
return stack.insert(0, ‘:error:’)
stack.pop(0)
stack.pop(0)
newTop = x%y
return stack.insert(0, str(newTop))
else:
return stack.insert(0, ‘:error:’)
def doPop(stack):
if len(stack) < 1:
return stack.insert(0, ‘:error:’)
else:
return stack.pop(0)
def doPush(stack, line):
getList = line.split()
if getList[1][0] == ‘-‘:
if getList[1][1:] == ‘0’:
return stack.insert(0,’0′)
elif getList[1][1:].isdigit():
return stack.insert(0, getList[1])
else:
return stack.insert(0, ‘:error:’)
elif getList[1].isdigit():
return stack.insert(0, getList[1])
elif re.match(‘^[a-zA-Z].*’,getList[1],0):
return stack.insert(0, getList[1])
elif re.match(‘^”.+”$’,getList[1],0):
return stack.insert(0, getList[1])
else:
return stack.insert(0, ‘:error:’)
def doSwap(stack):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
else:
x = stack[1]
y = stack[0]
stack.pop(0)
stack.pop(0)
stack.insert(0, y)
return stack.insert(0, x)
def doNeg(stack, hm):
if len(stack) < 1:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if s0.isdigit:
x = int(s0)
stack.pop(0)
newTop = -1*x
return stack.insert(0, str(newTop))
else:
return stack.insert(0, ‘:error:’)
def doQuit(stack, f):
for ele in stack:
f.write(ele.strip(‘”‘) + ‘\n’)
f.close()
def parseBooleanOrError(line, stack, hm):
if line[1] == ‘e’:
return stack.insert(0,’:error:’)
elif line[1] == ‘t’:
return stack.insert(0,’:true:’)
else:
return stack.insert(0,’:false:’)
def doIf(stack, hm):
if len(stack) < 3:
return stack.insert(0, ‘:error:’)
else:
s2 = str(stack[2])
if s2 != ‘:true:’ and s2 != ‘:false:’:
s2 = str(hm.get(s2,s2))
if s2 == ‘:true:’:
stack.pop(2)
stack.pop(1)
return stack
elif s2 == ‘:false:’:
stack.pop(2)
stack.pop(0)
return stack
else:
return stack.insert(0,’:error:’)
def doNot(stack, hm):
if len(stack) < 1:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
if s0 != ‘:true:’ and s0 != ‘:false:’:
s0 = str(hm.get(s0,s0))
if s0 == ‘:true:’:
stack.pop(0)
stack.insert(0,’:false:’)
return stack
elif s0 == ‘:false:’:
stack.pop(0)
stack.insert(0,’:true:’)
return stack
else:
return stack.insert(0,’:error:’)
def doAnd(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if s0 != ‘:true:’ and s0 != ‘:false:’:
s0 = str(hm.get(s0,s0))
if s1 != ‘:true:’ and s1 != ‘:false:’:
s1 = str(hm.get(s1,s1))
if s0 == ‘:false:’ and s1 == ‘:false:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:false:’)
return stack
elif s0 == ‘:false:’ and s1 == ‘:true:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:false:’)
return stack
elif s0 == ‘:true:’ and s1 == ‘:false:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:false:’)
return stack
elif s0 == ‘:true:’ and s1 == ‘:true:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:true:’)
return stack
else:
return stack.insert(0,’:error:’)
def doOr(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if s0 != ‘:true:’ and s0 != ‘:false:’:
s0 = str(hm.get(s0,s0))
if s1 != ‘:true:’ and s1 != ‘:false:’:
s1 = str(hm.get(s1,s1))
if s0 == ‘:false:’ and s1 == ‘:false:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:false:’)
return stack
elif s0 == ‘:false:’ and s1 == ‘:true:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:true:’)
return stack
elif s0 == ‘:true:’ and s1 == ‘:false:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:true:’)
return stack
elif s0 == ‘:true:’ and s1 == ‘:true:’:
stack.pop(0)
stack.pop(0)
stack.insert(0,’:true:’)
return stack
else:
return stack.insert(0,’:error:’)
def doEqual(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
stack.pop(0)
stack.pop(0)
if x==y:
return stack.insert(0, ‘:true:’)
else:
return stack.insert(0, ‘:false:’)
else:
return stack.insert(0, ‘:error:’)
def doLessThan(stack, hm):
if len(stack) < 2:
return stack.insert(0, ‘:error:’)
elif stack[0][0] == ‘:’ or stack[1][0] == ‘:’:
return stack.insert(0, ‘:error:’)
else:
s0 = str(stack[0])
s1 = str(stack[1])
if re.match(‘^[a-zA-Z].*’,s0,0):
s0 = str(hm.get(s0,s0))
if re.match(‘^[a-zA-Z].*’,s1,0):
s1 = str(hm.get(s1,s1))
if s0.isdigit and s1.isdigit:
y = int(s0)
x = int(s1)
stack.pop(0)
stack.pop(0)
if x<y:
return stack.insert(0, ‘:true:’)
else:
return stack.insert(0, ‘:false:’)
else:
return stack.insert(0, ‘:error:’)
def doBind(stack, hm):
if len(stack) < 2:
return stack.insert(0,’:error:’)
else:
s0 = stack[0]
s1 = stack[1]
if re.match(‘^[a-zA-Z].*’,stack[1],0) and stack[0] != ‘:error:’:
stack.pop(0)
stack.pop(0)
s0 = str(hm.get(s0,s0))
hm[s1] = s0
return stack.insert(0,’:unit:’)
else:
return stack.insert(0,’:error:’)
(* CSE305 Spring 2016
* A possible solution to HW2, expressed in Standard ML
* Author: Carl Alphonce
* Modified: Lu Meng
*)
(****************************************************************************
TYPE DEFINITIONS
****************************************************************************)
(* The type of expressions and special forms *)
datatype exp =
Boolean of bool
| Number of int
| String of string
| Name of string
| Error | Quit | Add | Sub | Mul | Div | Rem | Pop | Swap | Neg |
And | Or | Not | Bind | Equals | LessThan | If | Let | End | Unit;
(****************************************************************************
UTILITY FUNCTIONS
****************************************************************************)
(* Utility function to build a textual form of an expression
or special form, used for printing.
*)
fun expression2string(Boolean(true)) = “:true:”
| expression2string(Boolean(false)) = “:false:”
| expression2string(String(s)) = s
| expression2string(Number(X)) = if (X<0) then “-“^Int.toString(~X) else Int.toString(X)
| expression2string(Error) = “:error:”
| expression2string(Unit) = “:unit:”
| expression2string(Name(x)) = x
| expression2string(Let) = “let”
| expression2string(End) = “end”
| expression2string(_) = “?? should not happen ??”
;
(* Computes quotient according to rules of the language *)
fun quotient(a2,a1) =
if (a1<0)
then if (a2 div a1) * a1 > a2 then (a2 div a1)+1 else (a2 div a1)
else (a2 div a1);
(* Computes remainder according to rules of the language *)
fun remainder(a2,a1) = a2 – a1 * quotient(a2,a1);
(****************************************************************************
MAIN EVALUATOR FUNCTIONS
****************************************************************************)
(* Applies a primitive function to its two arguments *)
fun
(* 0-ARY OPERATORS *)
apply(_,[])  = (Error,[])
(* UNARY OPERATORS *)
| apply(Neg,Number(a)::rest) = (Number(~a),rest)
| apply(Not,Boolean(a) :: rest) = (Boolean(not a), rest)
| apply(_,[x]) = (Error,[x])
(* BINARY OPERATORS *)
| apply(Add,Number(a1)::Number(a2)::rest) = (Number(a2+a1),rest)
| apply(Sub,Number(a1)::Number(a2)::rest) = (Number(a2-a1),rest)
| apply(Mul,Number(a1)::Number(a2)::rest) = (Number(a2*a1),rest)
| apply(Div,Number(a1)::Number(a2)::rest) = (if a1 = 0 then (Error,Number(a1)::Number(a2)::rest) else (Number(quotient(a2,a1)),rest))
| apply(Rem,Number(a1)::Number(a2)::rest) = (if a1 = 0 then (Error,Number(a1)::Number(a2)::rest) else (Number(remainder(a2,a1)),rest))
| apply(Equals, Number(a1) :: Number(a2) :: rest) = (Boolean(a2 = a1), rest)
| apply(LessThan, Number(a1) :: Number(a2) :: rest) =  (Boolean(a2 < a1), rest)
| apply(And, Boolean(a1) :: Boolean(a2) :: rest) =  (Boolean(a2 andalso a1), rest)
| apply(Or, Boolean(a1) :: Boolean(a2) :: rest) =  (Boolean(a2 orelse a1), rest)
(*  TERNARY OPERATORS *)
| apply(If, a1 :: a2 :: Boolean(true) :: rest) =  (a1, rest)
| apply(If, a1 :: a2 :: Boolean(false) :: rest) =  (a2, rest)
(*Anything else results in an error *)
| apply(_,stack) = (Error,stack)
;
(* Functions to look up name in the list of environments *)
fun lookup2(Name(x),[]) = NONE
| lookup2(Name(x), (Name(y),value)::bindings) =
if (x=y) then SOME(value)
else lookup2(Name(x),bindings)
| lookup2(_,_) = SOME(Error);
fun lookup(Name(x),[]) = Name(x)
| lookup(Name(x),e::es) = (
case (lookup2(Name(x),e)) of
NONE => lookup(Name(x),es)
| SOME(v) => v )
| lookup(_,_) = Error;
(* Function to check if a name is bound *)
fun isBound(Name(x),[]) = NONE
| isBound(Name(x),e::es) = (
case (lookup2(Name(x),e)) of
NONE => isBound(Name(x),es)
| SOME(v) => SOME(v))
| isBound(_,_) = SOME(Error);
fun bind(Error::Name(n)::rest, e :: es) = (Error::Name(n)::rest, e :: es)
| bind(Unit::Name(n)::rest, e::es) = (Unit::rest,((Name(n),Unit)::e)::es)
| bind(String(s) :: Name(n) :: rest, e::es) =  (Unit::rest, ((Name(n),String(s))::e)::es)
| bind(Number(x) :: Name(n) :: rest, e::es) =  (Unit::rest, ((Name(n),Number(x))::e)::es)
| bind(Boolean(s) :: Name(n) :: rest, e::es) =  (Unit::rest, ((Name(n),Boolean(s))::e)::es)
| bind(Name(value) ::Name(n)::rest, e::es) =  (
case (isBound(Name(value),e::es)) of
NONE => (Error:: Name(value) :: Name(n) ::rest, e::es)
| SOME(c) => (Unit::rest, ((Name(n),c)::e)::es)
)
| bind(value::Name(n)::rest, e::es) =  (
case (isBound(value,e::es)) of
NONE => (Unit::rest, ((Name(n),value)::e)::es)
| SOME(c) => (Unit::rest,((Name(n),c)::e)::es) )
| bind(stack,envs) = (Error::stack, envs);
| bind(value ::Name(n)::rest, e::es) =  (
case (isBound(Name(n),e::es)) of
NONE => (Unit::rest, ((Name(n),value)::e)::es)
| SOME(c) => (Unit::rest, ((Name(n),c)::e)::es)
)
| bind(stack,envs) = (Error::stack, envs);
fun doPop(Let :: rest) = rest
| doPop(a :: b) = doPop(b)
| doPop([]) = [] ;
fun doLet(stack, envs) = ( Let :: stack,envs);
fun doEnd(a :: rest, envs) = ( a :: doPop(rest),envs) ;
(* stack operations *)
fun stackOps(Pop, x::stack) = stack
| stackOps(Swap, x::y::stack) = y::x::stack
| stackOps(_,stack) = Error::stack
;
(* Evaluates an expression *)
fun eval(Boolean(x), stack, env) = (Boolean(x)::stack , env)
| eval(Number(x), stack , env)  = (Number(x)::stack , env)
| eval(Name(x), stack, env)    = (lookup(Name(x),env)::stack, env)
| eval(Bind, stack, env)       = bind(stack, env)
| eval(Let,stack,env) = doLet(stack,env)
| eval(End,stack,env) = doEnd(stack,env)
| eval(Quit, stack, env)       = (Quit::stack , env)
| eval(Pop, x::stack, env)     = (stack , env)
| eval(String(x), stack, env)  = (String(x)::stack,env)
| eval(Swap, x::y::stack , env)     = (y::x::stack, env)
| eval(Error, stack , env)      = (Error::stack,env)
| eval(Unit,stack , env) = (Unit::stack, env)
| eval(expr, stack , env) = let
val (v,s) = apply(expr, stack)
in
(v::s , env)
end;
(* Functions to parse a number *)
fun parseNumber(x,inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (Char.isDigit(ch)) then parseNumber(x*10+(ord(ch)-ord(#”0″)),inStr)
else if (Char.isSpace(ch)) then SOME(Number(x))
else SOME(Error)
;
fun parseNegativeNumber(inStr) =
case ( parseNumber(0,inStr) ) of
NONE => SOME(Error)
| SOME(Number(num)) =>  SOME(Number(~1 * num))
| SOME(_) => SOME(Error)
;
(* Function to parse a boolean  *)
fun parseBoolean(x, inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (Char.isAlpha(ch) orelse ch = #”:”) then parseBoolean(x^Char.toString(ch),inStr)
else if (Char.isSpace(ch))
then if (x = “:true:”)  then SOME(Boolean(true))
else if (x = “:false:”) then SOME(Boolean(false))
else SOME(Error)
else SOME(Error);
(* Function to parse an error *)
fun parseError(x, inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (Char.isAlpha(ch) orelse ch = #”:”) then parseError(x^Char.toString(ch),inStr)
else if (Char.isSpace(ch))
then if (x = “:error:”)  then SOME(Error)
else SOME(Error)
else SOME(Error);
(***** EDITED TO HERE ********************************************************************)
(* Function to parse a boolean or error  *)
fun parseString(x, inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (ch = #”\””) then SOME(String(x))
else parseString(x^Char.toString(ch),inStr)
fun parseBooleanOrError(x, inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (ch = #”e”)                  then parseError(x^Char.toString(ch),inStr)
else if (ch = #”t” orelse ch = #”f”) then parseBoolean(x^Char.toString(ch),inStr)
else SOME(Error);
(* Function to parse a primitive  *)
fun parsePrimitive(x, inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (Char.isAlpha(ch) orelse Char.isDigit(ch))  then parsePrimitive(x^Char.toString(ch),inStr)
else if (ch = #”\n”)
then if (x = “add”) then SOME(Add)
else if (x = “sub”) then SOME(Sub)
else if (x = “mul”) then SOME(Mul)
else if (x = “div”) then SOME(Div)
else if (x = “rem”) then SOME(Rem)
else if (x = “pop”) then SOME(Pop)
else if (x = “swap”) then SOME(Swap)
else if (x = “neg”) then SOME(Neg)
else if (x = “and”) then SOME(And)
else if (x = “or”) then SOME(Or)
else if (x = “not”) then SOME(Not)
else if (x = “equal”) then SOME(Equals)
else if (x = “lessThan”) then SOME(LessThan)
else if (x = “if”) then SOME(If)
else if (x = “bind”) then SOME(Bind)
else if (x = “quit”) then SOME(Quit)
else if (x = “let”) then SOME(Let)
else if(x = “end”) then SOME(End)
else SOME(Name(x))
else SOME(Error);
fun parsePush(inStr) =
case (TextIO.input1(inStr)) of
NONE => SOME(Error)
| SOME(ch) =>
if (Char.isAlpha(ch)) then parsePush(inStr)
else if (Char.isSpace(ch))
then if (TextIO.input1(inStr) = SOME(c)) then
(if c = #”-“) then parseNegativeNumber(inStr)
else parseNumber(ord(TextIO.input1(inStr))-ord(#”0″),inStr))
else SOME(Error);
(* A recursive helper function for the parse function, which reads
a character from the input stream and determines what more
specific parsing function to call.
*)
fun parseHelper(NONE, inStr) = NONE
| parseHelper(SOME(ch), inStr) =
let
val line = Option.valOf (TextIO.inputLine inStr)
val second = String.sub (line, 0)
val inStr1 = TextIO.openString line
in
if (ch = #”p” andalso second = #”u”) then parseHelper(TextIO.input1(TextIO.openString (String.extract(line,4,NONE))), TextIO.openString (String.extract(line, 5, NONE)))
else if (Char.isDigit(ch)) then parseNumber(ord(ch)-ord(#”0″),inStr1)
else if (ch = #”-“)        then parseNegativeNumber(inStr1)
else if (ch = #”:”)        then parseBooleanOrError(“:”, inStr1)
else if (ch = #”\””)       then parseString(“”, inStr1)
else if (Char.isAlpha(ch)) then parsePrimitive(Char.toString(ch), inStr1)
else if (ch = #”\n”)       then parseHelper(TextIO.input1(inStr1), inStr1)
else NONE
end;
(* Function to parse the next expression on the input stream. *)
fun parse(inStr) = parseHelper(TextIO.input1(inStr), inStr);
fun hw4(inFile : string, outFile : string) =
let
val fileInp = TextIO.openIn inFile
val fileOut = TextIO.openOut outFile
fun printStack([]) = ()
| printStack(x::xs) = ( TextIO.output (fileOut, (expression2string(x)^”\n”)) ; printStack(xs) );
fun replHelper(inStr, (stack,env)) =
(
case (parse(inStr)) of
NONE => replHelper(inStr, (stack,env))
| SOME(Quit) => (printStack(stack); TextIO.closeIn fileInp; TextIO.closeOut fileOut)
| SOME(expression) => replHelper(inStr,eval(expression, stack,env))
);
in
replHelper(fileInp, ([],[[]]))
end
val _ = hw3(“input.txt”, “output.txt”)

Saturday, 20 August 2016

Programming and learning CS when legally blind

Since I’ve been using blocks-based languages lately, I’ve been thinking more about the challenges of using blocks-based languages, and programming and learning CS more generally, when legally blind.  One of our PhD students in the Human-Centered Computing PhD program is legally blind, and he generously came to visit me and brought with him one of his students who is legally blind and learning programming.


The first and biggest surprise for me was that most (about 85%) legally blind people can actually see. One of the people I worked with can see light/dark (which doesn’t help with programming, but does help him with way-finding and spatial navigation). The other one loves to program in App Inventor using high magnification on her Mac. She’s low-vision and finds the large splotches of color useful in figuring out her code.
The implication, they explained to me, is that some tactile-based affordances for blind people don’t work because low-vision blind people would prefer to use audio and what sight they have, rather than learn a touch-based encoding. I was surprised to learn that most blind people don’t learn Braille because it’s a complicated code, and low vision people would rather magnify the screen than learn the encoding.
Blind programmers who know Braille will often use an audio screen reader along with a Braille reader for a single line of text. It’s easier to scan a line (especially for syntax errors) with Braille than with a screen reader.
The second surprise was about their tools. They showed me Visual Studio and EdSharp, a plain text editor developed by a blind programmer for blind programmers. I asked what features made an editor good for blind programmers. They said, “It works with screen readers.” And really, that’s it. They don’t want specialized tools with non-standard interfaces because of the cognitive load of switching between the standard screen reader interfaces and a novel interface.


I didn’t realize how few tools go to the trouble of accessing the screen reader API’s and providing good mappings from the interface to text. Processing (all platforms) and NetBeans (on Windows) are completely unusable for blind people because they are inaccessible by screen readers. Visual Studio has become a new favorite IDE, not because of any special features, but because it does “it doesn’t crash and I can access it with a screen reader.”
I was particularly interested in the low-vision programmer’s use of App Inventor. We talked about what didn’t work for her and brainstormed what would make it better. One of the tougher parts of block-based languages is that scripts could be anywhere in a 2-D space. It’s hard to scan a 2-D space with a zoomed interface, and there’s no obvious interface for screen-readers. Having blocks snap to a grid would help a lot to make it easier to find scripts for both types of blind programmers.
We talked about how CS classes might be better designed for legally blind students. I was surprised to learn how much they dislike active learning activities in classrooms.  They said that



when the whole class breaks into small group discussions, they can’t hear their group.  The definition of the group is by physical proximity, but they discern “close” by “loud.”  They end up listening in to whichever group is loudest around them.  They need a different kind of active learning activity.