Convert number to letter

If you are allowed to use an extension then this extension can be useful for you.
(I think this extension works offline too)

1 Like

@oseamiya Thanks

But I'm planning to do it all by myself.

Cuz, that has allowed me do things that are not present in MIT AI2 by default. These are important procedures (methods) such as,

String s = "Hello World!"

// (1)
s.IndexOf('e');
// (2)
boolean b1 = s.matches("Hello World!"); // true
boolean b2 = s.matches("Hi"); //false

And some more useful operations.

According to me this will help many users.

So I'm gonna do this project all by myself.

I'm first doing this in Java.
Next, I'll copy the whole thing in the form of MIT App Inventor 2 Blocks.

um...

image

3 Likes

@TIMAI2

I said String.indexOf();
The method which returns an int value.

or rather you may think it as String.charAt(); method.

Also, I said String.matches(String);

Which returns true if both the Strings are same.

How could you find a String.contains(String); method in my post ? :thinking:

So, you can can find java codes if you search on google and you can try creating it through blocks.

3 Likes

Here is also a Stack Overflow answer. (also with numbers to :fr: French words)

1 Like

Thanks @oseamiya and @Gordon_Lu

But, I didn't see that before actually. :sweat_smile:

Had to do it all by myself.

At last the java code is done.

Its 1:57 AM here and I think now its time to get to sleep after this success.

BTW, my program can convert any long value to words, both in negative and positive (not decimals).

Also, BTW, long values go till pentillions.

Conversion

(1 pentillion = 1000000 trillion)

I took me quite a lot of thinking and two days to make it in java.

And I know putting it in MIT AI2 would be a hard task too.

But I'm gonna do it. (Obviously after some sleep, cuz I mentioned the present time.)

Bye. :wave:

Here is the Java Program :

package Practice.Program;

public class Num2Words {
  
  private static long number;
  private static String words = new String("");
  
  public Num2Words(long n){ number = n; }
  
  static String[] tp = {"", "thousand ", "million ", "billion ", "trillion ", "quadrillion ", "pentillion "};
  static String[] od = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
  static String[] td = {"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
  static String[] tn = {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
  
  public String toWords(){
    words = Long.toString(number);
    int l = words.length();
    boolean n = false;
    
    if (number < 0){ n = true; number *= -1; --l;}
    
    breaker : for (byte LOL = 0; LOL < 1; LOL++){
      
      if (StringHasChar(words, '.')){ words = "Decimals not supported."; break breaker;}
      if (l>19){ words = "too big"; break breaker;}
      
      if (l==1)      words = oneDigit(number);                    // one digit
      
      else if (l==2) words = twoDigits(number);                   // two digits 
      
      else if (l==3) words = threeDigits(number);                 // three digits
      
      else words = nDigits(number);                               // multiple digits
      
    }
    
    if (n == true) {words = "Minus "+words; number *= -1;}
   return words;
  }
  
  private static String oneDigit(long n){
    char[] ns = Long.toString(n).toCharArray();
    return od[(char2num(ns[0]))];
  }
  
  private static String twoDigits(long n){
    String s = "";
    char[] ns = Long.toString(n).toCharArray();
    if (n < 20){
      s = td[(char2num(ns[1]))];
    } else if (n < 100){
        s = tn[char2num(ns[0])];
        if (char2num(ns[1])!=0){ s += " " + od[char2num(ns[1])]; }
      }
    return s;
  }
  
  private static String threeDigits(long n){
    String s = "", is = Long.toString(n);
    long[] ns = String2longArray(is);
    
    s = od[(int)(ns[0])] + " hundred";
    if (ns[1]!=0&&ns[2]!=0){
      long i = (ns[1])*10+(ns[2]);
      s += " " + twoDigits(i);
    } else {
        if (ns[1]!=0) s += " " + twoDigits((ns[1]*10)); 
        if (ns[2]!=0) s += " " + oneDigit(ns[2]);
      }
    
    return s;
  }
  
  private static String nDigits(long n){
    String s = threeDigits(n);
    int tpi = ((digits(n)+2)/3)-1, rtpi = 0;
    long[] tfr = threeFromRight(n);
    s = "";
    
    for (; tpi >= 0; tpi--, rtpi++){
      s = new Num2Words(tfr[tpi]).toWords() + " " + tp[rtpi] + s;
    }
    
    return s;
  }
  
  private static int digits(long n){
    long ans = 0;
    for (; n>0; n/=10, ans++);
    return (int)(ans);
  }
  
  private static long[] threeFromRight(long n){
    int tpi = (digits(n)+2)/3, nl = digits(n);
    long[] ans=new long[tpi], ia=String2longArray(Long.toString(n)), ta=new long[3];
    
    for (int i=nl, t=2, c=0, l=tpi*3; l >= 0; l--, c++, i--, t--){
      try {ta[t] = ia[i-1];}
      catch (ArrayIndexOutOfBoundsException e){ta[t]=0;}
      if (((c+1)%3)==0){ 
        --tpi;
        ans[tpi] = longArrays2long(ta);
        
        t = 3;
        c = -1;
      }
    }
    
    return ans;
  }
  
  private static int char2num(char c){
    char[] ca = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    byte ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},  ans = -1;
    
    for (byte i = 0; i < 10; i++){ if (c == ca[i]){ ans = ia[i]; break;} }
    return ans;
  }
  
  private static long[] String2longArray(String s){
    char[] ca = s.toCharArray();
    byte l = (byte)s.length();
    long[] ans = new long[l];
    
    for (byte i = 0; i < l; i++){ ans[i] = char2num(ca[i]); }
    return ans;
  }
  
  private static long longArrays2long(long[] ia){
    long ans = 0;
    try { for (int i = 0; i >= 0; ans += ia[i], ans *= 10, ++i); } 
    catch (ArrayIndexOutOfBoundsException e){}
    ans/=10;
    
    return ans;
  }
  
  private static boolean StringHasChar(String s, char c){
    char[] sca = s.toCharArray();
    byte l = (byte)(s.length());
    boolean ans = false;
    for (byte i = 0; i > l; i++){
      if (sca[i] == c) ans = true;
    }
    return ans;
  }
  
  public static void main(String[] args){
    long n = -1053664648543756767l;
    String words = new Num2Words(n).toWords();
    
    System.out.println(n + " : " + words);
  }
  
}

I've also posted my program as an answer to a question in Stack Overflow.


Would anyone like to help me out with putting some procedures into MIT AI2 ?

If Yes

How you can help me :-

  1. Make an aia.
  2. Make the procedures.
  3. Send the aia.

Helping me is fully your own wish. I'd not force anyone.

Thank You.

Why do you put your code in a stack overflow question from 2011! that is about converting a number to word in Iphone?

2 Likes

Didn't see the date actually. :sweat_smile:

Actually, a lot of Stack Overflow Java questions are old, some are the same age or just a year smaller than my age.

Back to the topic, I am making an extension out of this.

EDIT: Wait a minute...seems that there is something wrong in the code.

2 Likes

LOL :joy:

Same with me too, I'm just about to be 15, and these questions are almost 13 years old LOL. :joy:

Noice.

@gordonlu310

Wait what, where ?
I tested the code with many numbers, actually.

Obviously, its not possible to test it for pentillions of numbers actually. :sweat_smile:

EDIT :

You can use this code snippet to test any number you wish.

Just add that number to the long array and run your code and see the terminal. You'd get the result.

  
  public static void main(String[] args){
    long[] la = {836463837l, 8373647738147l, 82726361882l, 63652772l, 6726263637l};
    String words = "";
    try {  for (int i = 0; i>=0; i++){
             words = new Num2Words(la[i]).toWords();
             System.out.println(la[i] + " : " + words);
           }
    } catch (ArrayIndexOutOfBoundsException e){}
  }
  

Pls tell me if you find any mistake and I'll fix it.

Pls don't forget to give me a small credit if you use my code. I never got a credit b4. :cry:

This is from the Stack Overflow answer that received 100+ upvotes, and is capable of 12 digits in English. I will post it like an extension here.

Successfully made English translation. I am still working on it.

image

Note: if you want to do this in Screen.Initialize, you need to wait 200 ms first in order to start converting.

1 Like

Ok, just do it. :upside_down_face:

I'm make mine myself when learn about making them.

Finally completed, English and French. Currently, this is only capable of 12 digits (hundred billions).

Event blocks

GotResult

image

This event is fired when the extension has received the conversion result.

Parameters: languageCode = text, result = text

Method blocks

NumbersToEnglish

image

Converts numbers to English numerals and calls the GotResult event when this is finished.

Parameters: number = (long)

NumbersToFrench

image

Converts numbers to French numerals and calls the GotResult event when this is finished.

Parameters: number = (long)

:inbox_tray: Downloads

AIX:
com.gordonlu.numbers2words.aix (9.9 KB)

:lock: Open Source

Here you go.

package com.gordonlu.numbers2words;

import android.app.Activity;
import android.content.Context;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.lang.Integer;

@DesignerComponent(
        version = 1,
        description = "A non-visible extension that automatically converts numbers to words.",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,
        iconName = "https://docs.google.com/drawings/d/e/2PACX-1vQCI87PHLBF0jb8QWyYmIRQSjjNW3EFXf-qpsWCvBYkUQ9vEgPAB8SpxcMpblxNpbIYrjCjLrRLIU2c/pub?w=16&h=16")

@SimpleObject(external = true)
//Libraries
@UsesLibraries(libraries = "")
//Permissions
@UsesPermissions(permissionNames = "")

public class Numbers2Words extends AndroidNonvisibleComponent {

    //Activity and Context
    private Context context;
    private Activity activity;

    public Numbers2Words(ComponentContainer container){
        super(container.$form());
        this.activity = container.$context();
        this.context = container.$context();
    }

    // https://stackoverflow.com/a/3911987/17802442

    private static final String[] tensNames = {""," ten"," twenty"," thirty"," forty"," fifty"," sixty"," seventy"," eighty"," ninety"};

    private static final String[] numNames = {""," one"," two"," three"," four"," five"," six"," seven"," eight"," nine"," ten",
    " eleven"," twelve"," thirteen"," fourteen"," fifteen"," sixteen"," seventeen"," eighteen"," nineteen"
  };

  private static final String[] dizaineNames = { "","","vingt","trente","quarante","cinquante","soixante","soixante","quatre-vingt","quatre-vingt"};

  private static final String[] uniteNames1 = {"","un","deux","trois","quatre","cinq","six","sept","huit","neuf","dix","onze","douze","treize","quatorze",
    "quinze","seize","dix-sept","dix-huit","dix-neuf"};

  private static final String[] uniteNames2 = {"","","deux","trois","quatre","cinq","six","sept","huit","neuf","dix"};

    private static String convertLessThanOneThousand(int number) {
        String soFar;
        if (number % 100 < 20){
            soFar = numNames[number % 100];
            number /= 100;
        } else {
            soFar = numNames[number % 10];
            number /= 10;
            soFar = tensNames[number % 10] + soFar;
            number /= 10;
        }
        if (number == 0) return soFar;
        return numNames[number] + " hundred" + soFar;
    }

    public static String convert(long number) {
        if (number == 0) { 
            return "zero"; 
        }
        String snumber = Long.toString(number);
        String mask = "000000000000";
        DecimalFormat df = new DecimalFormat(mask);
        snumber = df.format(number);
        int billions = Integer.parseInt(snumber.substring(0,3));
        int millions  = Integer.parseInt(snumber.substring(3,6));
        int hundredThousands = Integer.parseInt(snumber.substring(6,9));
        int thousands = Integer.parseInt(snumber.substring(9,12));

        String tradBillions;
        switch (billions) {
        case 0:
            tradBillions = "";
            break;
        case 1 :
            tradBillions = convertLessThanOneThousand(billions) + " billion ";
            break;
        default :
            tradBillions = convertLessThanOneThousand(billions) + " billion ";
        }
        String result =  tradBillions;
        String tradMillions;
        switch (millions) {
        case 0:
            tradMillions = "";
            break;
        case 1 :
            tradMillions = convertLessThanOneThousand(millions) + " million ";
            break;
        default :
            tradMillions = convertLessThanOneThousand(millions) + " million ";
    }
    result =  result + tradMillions;
    String tradHundredThousands;
    switch (hundredThousands) {
    case 0:
      tradHundredThousands = "";
      break;
    case 1 :
      tradHundredThousands = "one thousand ";
      break;
    default :
      tradHundredThousands = convertLessThanOneThousand(hundredThousands)
         + " thousand ";
    }
    result =  result + tradHundredThousands;
    String tradThousand;
    tradThousand = convertLessThanOneThousand(thousands);
    result =  result + tradThousand;
    return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
  }

    @SimpleFunction(description = "Converts numbers to English numerals and calls the GotResult event when this is finished.")
    public void NumbersToEnglish(long number) {
        String result = convert(number);
        GotResult("en", result);
    }

    @SimpleFunction(description = "Converts numbers to French numerals and calls the GotResult event when this is finished.")
    public void NumbersToFrench(long number) {
        String result = convertF(number);
        GotResult("fr", result);
    }

    @SimpleEvent(description = "This event is fired when the extension has received the conversion result.")
    public void GotResult(String languageCode, String result) {
        EventDispatcher.dispatchEvent(this, "GotResult", languageCode, result);
    }

  private static String convertZeroToHundred(int number) {
    int laDizaine = number / 10;
    int lUnite = number % 10;
    String resultat = "";
    switch (laDizaine) {
    case 1 :
    case 7 :
    case 9 :
      lUnite = lUnite + 10;
      break;
    default:
    }
    String laLiaison = "";
    if (laDizaine > 1) {
      laLiaison = "-";
    }
    switch (lUnite) {
    case 0:
      laLiaison = "";
      break;
    case 1 :
      if (laDizaine == 8) {
        laLiaison = "-";
      }
      else {
        laLiaison = " et ";
      }
      break;
    case 11 :
      if (laDizaine==7) {
        laLiaison = " et ";
      }
      break;
    default:
    }
    switch (laDizaine) {
    case 0:
      resultat = uniteNames1[lUnite];
      break;
    case 8 :
      if (lUnite == 0) {
        resultat = dizaineNames[laDizaine];
      }
      else {
        resultat = dizaineNames[laDizaine] + laLiaison + uniteNames1[lUnite];
      }
      break;
    default :
      resultat = dizaineNames[laDizaine] + laLiaison + uniteNames1[lUnite];
    }
    return resultat;
  }

  private static String convertLessThanOneThousandF(int number) {
    int lesCentaines = number / 100;
    int leReste = number % 100;
    String sReste = convertZeroToHundred(leReste);
    String resultat;
    switch (lesCentaines) {
    case 0:
      resultat = sReste;
      break;
    case 1 :
      if (leReste > 0) {
        resultat = "cent " + sReste;
      }
      else {
        resultat = "cent";
      }
      break;
    default :
      if (leReste > 0) {
        resultat = uniteNames2[lesCentaines] + " cent " + sReste;
      }
      else {
        resultat = uniteNames2[lesCentaines] + " cents";
      }
    }
    return resultat;
  }

  public static String convertF(long number) {
    if (number == 0) { return "zéro"; }
    String snumber = Long.toString(number);
    String mask = "000000000000";
    DecimalFormat df = new DecimalFormat(mask);
    snumber = df.format(number);
    int lesMilliards = Integer.parseInt(snumber.substring(0,3));
    int lesMillions  = Integer.parseInt(snumber.substring(3,6));
    int lesCentMille = Integer.parseInt(snumber.substring(6,9));
    int lesMille = Integer.parseInt(snumber.substring(9,12));
    String tradMilliards;
    switch (lesMilliards) {
    case 0:
      tradMilliards = "";
      break;
    case 1 :
      tradMilliards = convertLessThanOneThousandF(lesMilliards)
         + " milliard ";
      break;
    default :
      tradMilliards = convertLessThanOneThousandF(lesMilliards)
         + " milliards ";
    }
    String resultat =  tradMilliards;

    String tradMillions;
    switch (lesMillions) {
    case 0:
      tradMillions = "";
      break;
    case 1 :
      tradMillions = convertLessThanOneThousandF(lesMillions)
         + " million ";
      break;
    default :
      tradMillions = convertLessThanOneThousandF(lesMillions)
         + " millions ";
    }
    resultat =  resultat + tradMillions;

    String tradCentMille;
    switch (lesCentMille) {
    case 0:
      tradCentMille = "";
      break;
    case 1 :
      tradCentMille = "mille ";
      break;
    default :
      tradCentMille = convertLessThanOneThousandF(lesCentMille)
         + " mille ";
    }
    resultat =  resultat + tradCentMille;

    String tradMille;
    tradMille = convertLessThanOneThousandF(lesMille);
    resultat =  resultat + tradMille;

    return resultat;
  }
}

2 Likes

All well and good, but you started this Topic with a different requirement - to "convert number to letter", thus wasting a lot of our time!

1 Like

@ChrisWard

Are u somehow meaning that I started the topic ?

LOL :joy:

If you actually mean that I stated the topic, click here

This topic was actually started by @BLACK_GHOST

1 Like

Sorry Shubhamr69, of course you are not the author of this Topic, my mistake.

Your effort does not meet Black Ghost's requirement though, unless/he she has moved the original goal posts into midfield.