Questions about the state of the Intelligent Character Recognition (ICR)

I am looking for a little advice on a project that I am considering. This is in the area of ​​OCR / ICR and I wonder how precise ICR has become? There are obviously commercial solutions within Azure and Google as well as some open source options.

My project would involve preprinted forms which would be completed by pen by hand. I imagine that almost all of them would be printed (not cursive).

I guess I am trying to understand at this point if there is a solution (open to a commercial solution) which, for example, can read letters where lines can cross the letter (this is that is, the person who filled it did not write 100% in the open space, but instead got lost in the field line, etc. In addition, the 39; can one of these solutions manage the check boxes AND identify the elements circled. (For example, FT / PT / NA) Full time, part time, not applicable. If a user has drawn a circle around the One of these options, is there a way to identify which of these options are enclosed in a circle?

Does anyone also have an idea if there are business options that allow you to easily identify the fields and then specify what you want to do with the data from those fields?

It seems that the Azure ink and shape recognizer is a combination of what I'm looking for. I'm curious to know if, for example, the Form Recognizer works with a combination of typed and handwritten text.

Are you looking for someone who can get a feel for what this type of project is and what is currently possible? Is there an OCR / ICR solution that has achieved human parity?

TIA!

some questions about the matrix

Thanks for contributing to the answer to Math Stack Exchange!

  • Make sure you respond to the question. Give details and share your research!

But to avoid

  • Ask for help, clarification or respond to other responses.
  • Make statements based on opinion; save them with references or personal experience.

Use MathJax to format the equations. Reference MathJax.

For more information, see our tips on writing correct answers.

4 Go-To apps for review and exam preparation

After so many weeks writing essays, reports, end-of-term articles and other academic work, it's high time to start revising the exams. This period of student life is really difficult, especially for those who weren't serious enough with classroom activities. Students who have not taken notes during class have a hard time preparing for exams. As a rule, their memory is not clear enough to keep in mind all the details that their teacher said. Learners have a lot of trouble before their exams. They have to spend long hours in libraries reading a lot of sources and doing extensive research. Don't you want to be one of those students with their hands full? Get the most popular academic help apps that will make revision more effective and less stressful. Download them to your mobile phone and revise them for university exams like a pro.
Study Blue
If you are a fan of memory cards, consider a Study Blue study app. It is a free application, so you can download it to your device and get quick help from the outsourced material library. This app can be used to create and share memory cards, to add sound and images to your study material, to check subject knowledge by taking tests and continuing to progress. After downloading this app you will have access to an impressive library of study materials and helpful guides created by the students.

SpeedyPaper Advisor
Another useful application for all students is SpeedyPaper Adviser. This writing app will help you increase your grades and prepare you for exams more effectively. By having SpeedyPaper Adviser on your phone, you will have unlimited access to the huge database of college and university documents. You will be able to consult examples of various academic works. Find the essays, reports, research articles, coursework needed and increase your grades. Students will know how to create, structure and quote assignments. Customer support is available 24 hours a day, so if you're having trouble finding the required paper, you can contact managers and ask any questions. Many positive comments about this app prove that it is really great and worth a try. To find out all the features, download an application on your mobile phone or visit their website.

Gojimo
This app was created to help students have a smooth review. Undergraduate students can use Gojimo both online and on mobile devices. An app contains useful content for learners and some quizzes. You can select an exam for which you want to revise, and it goes with a list of questions that may be asked. If you haven't found a required subject, you can contact support via instant messaging.

Quizlet
This is another useful application for students who are going to prepare for exams. It's free, easy to use, and a good choice for self-study. Having Quizlet on your device, you can learn using memory cards, share them with your peers, learn foreign languages ​​and get more information on coding, math, science, history and other academic subjects. Many students benefit from Quizlet and leave positive feedback on this study app.

.

maintenance questions – Set up a micro service in Rust

Last year, I tried to implement a micro-service architecture in Rust. The imagined use case was a small izakaya store where digital orders could be given to the kichen tracked or deleted.

Looking for feedback on my coding style and architecture

https://github.com/simonsso/teketeke

Some sketches of the use cases
usecase1usecase2

and the code

main.rs

#(macro_use)
extern crate serde_derive;
extern crate hyper;
extern crate hyper_staticfile;
extern crate serde_json;

use std::error::Error;

use futures::{future, Future, Stream};
use hyper::{Body, Request, Response, Server, StatusCode};

use hyper::error::Error as hyper_errors;
use hyper::service::service_fn;
use lazy_static::lazy_static;

use regex::Regex;

use futures::task::spawn;
use futures_locks::RwLock;
use hyper_staticfile::FileChunkStream;
use tokio::fs::File;

#(derive(Copy, Deserialize, Clone, Serialize))
enum States {
    PENDING,
    DELIVERD,
    EMPTY,
}
#(derive(Deserialize, Clone, Serialize))
struct Record {
    itemname: String,
    id: usize,
    state: States,
    qty: i32,
    eta: u64,
}

struct Datastore {
    vault: Vec>>,
}

#(derive(Deserialize, Clone, Serialize))
struct TableRequestVec {
    tab: Vec,
}

#(derive(Deserialize, Clone, Serialize))
struct TableRequest {
    itemname: String,
    qty: i32,
    eta: u64,
}

fn datastore_rw_lock(num: usize) -> RwLock {
    let mut v: Vec>> = Vec::with_capacity(100);
    for _ in 0..num {
        v.push(RwLock::new(Vec::new()))
    }
    let d: Datastore = Datastore { vault: v };
    RwLock::new(d)
}

lazy_static! {
    // TODO verify the correctness of regexp in tests
    static ref RE_TABLE_NUM: Regex = Regex::new(r"^/table/(d+)(/(.*))?$").unwrap();
    static ref RE_TABLE:     Regex = Regex::new(r"^/table/?").unwrap();
    static ref RE_DOWNLOAD_FILE:Regex = Regex::new(r"^/(index.html|button.js)$").unwrap();
    static ref STORAGE:RwLock =datastore_rw_lock(101);   //init with tables upto 100
                                                                   // TODO this should be done on demand instead
    static ref ITEMNUM:RwLock =RwLock::new(0);             // Global uniq order num
}

fn get_global_num() -> usize {
    let mut retval = 0;
    let lock = ITEMNUM.write().map(|mut cnt| {
        *cnt += 1;
        retval = *cnt;
    });
    match spawn(lock).wait_future() {
        Ok(_x) => {}
        Err(_) => {}
    }
    retval
}

// Encapsulate response for hyper
fn microservice_handler(
    req: Request,
) -> Box, Error = std::io::Error> + Send> {
    let uri: String = req.uri().to_string();
    let method = req.method().to_string();

    if let None = RE_TABLE.captures(&uri) {
        return serve_file(&uri);
    }
    // Parse request URL with stored Regexp
    let (table, path): (Option, Option) = match RE_TABLE_NUM.captures(&uri) {
        Some(m) => {
            // this is checked to be an integer
            let tbl = m.get(1).unwrap().as_str().parse::().unwrap();
            match m.get(3) {
                Some(argument) => (Some(tbl), Some(argument.as_str().to_string())),
                None => (Some(tbl), None),
            }
        }
        None => (None, None),
    };

    match (method.as_ref(), table, path) {
        ("GET", Some(table), None) => {
            // GET all items for table t
            let table = table as usize;
            match table_get_all(table) {
                ApiResult::Ok(s) => Box::new(future::ok(
                    Response::builder().status(200).body(Body::from(s)).unwrap(),
                )),
                ApiResult::Err(code, s) => Box::new(future::ok(
                    Response::builder()
                        .status(code)
                        .body(Body::from(s))
                        .unwrap(),
                )),
            }
        }
        ("GET", None, None) => {
            // Get all items
            let comma: String = ",".to_string();
            let lock = STORAGE.read();
            let v = &spawn(lock).wait_future().unwrap().vault;

            //Reusing get from table code
            let mut bodychunks: Vec = Vec::new();
            bodychunks.push("{"tables":{".to_string());
            for i in 0..v.len() {
                match table_get_all(i) {
                    ApiResult::Ok(s) => {
                        let headerstring = format!(""{}":", i);
                        bodychunks.push(headerstring);
                        bodychunks.push(s);
                        bodychunks.push(comma.clone())
                    }
                    ApiResult::Err(code, msg) => {
                        //TODO This should not occour
                        println!("Enexpected error fetcing all data {} {} {}", i, code, msg);
                    }
                }
            }
            if bodychunks.last() == Some(&comma) {
                bodychunks.pop();
            }
            bodychunks.push("}}".to_string());
            let stream = futures::stream::iter_ok::<_, ::std::io::Error>(bodychunks);
            let body = Body::wrap_stream(stream);
            let resp = Response::builder().status(200).body(body).unwrap();
            Box::new(future::ok(resp))
        }
        ("POST", None, None) => {
            let resp = Response::builder()
                .status(501)
                .body(req.into_body())
                .unwrap();
            Box::new(future::ok(resp))
        }
        ("POST", Some(table), None) => {
            let lock = STORAGE.read();
            let tablelist = &spawn(lock).wait_future().unwrap().vault;
            match tablelist.get(table as usize) {
                //TODO replace None case and Some case here
                Some(_) => {
                    // Sic TODO: this finds the tables vector and then does not use it
                    let boxedresult = table_add_items(req.into_body(), table);
                    let f = boxedresult.map_err(teketeke_to_stdio_err).map(move |s| {
                        match s {
                            Ok(s) => Response::builder().status(200).body(Body::from(s)),
                            Err(TeketekeError::InternalError(s)) => {
                                Response::builder().status(417).body(Body::from(s))
                            }
                            _ => Response::builder()
                                .status(418)
                                .body(Body::from("Unknown error")),
                        }
                        .unwrap()
                    });
                    Box::new(f)
                }
                None => {
                    let err = "I am a tea pot Error: this table is not allocated - build a bigger restaurant";
                    let response = Response::builder()
                        .status(418)
                        .body(Body::from(err))
                        .unwrap();
                    Box::new(future::ok(response))
                }
            }
        }
        ("DELETE", Some(table), Some(path)) => {
            // Remove something from table t
            //Todo find a way to identify items in table tab... maybe with id
            let table = table as usize;
            match table_remove_item(table, path) {
                ApiResult::Ok(s) => Box::new(future::ok(
                    Response::builder().status(200).body(Body::from(s)).unwrap(),
                )),
                ApiResult::Err(code, s) => Box::new(future::ok(
                    Response::builder()
                        .status(code)
                        .body(Body::from(s))
                        .unwrap(),
                )),
            }
        }
        ("UPDATE", Some(_t), Some(_path)) => {
            // Change some object for instance when it is deliverd to table
            // Fall throu default response
            let ans = "Not implemented";
            let resp = Response::builder()
                .status(501)
                .body(Body::from(ans))
                .unwrap();
            Box::new(future::ok(resp))
        }
        _ => {
            // Unsupported operation
            // Fall throu default response
            let ans = "Not implemented";
            let resp = Response::builder()
                .status(501)
                .body(Body::from(ans))
                .unwrap();
            Box::new(future::ok(resp))
        }
    }
}

#(derive(Debug))
enum ApiResult {
    Ok(T),
    Err(u16, String),
}

fn table_get_all(table: usize) -> ApiResult {
    let lock = STORAGE.read();
    let v = &spawn(lock).wait_future().unwrap().vault;
    match v.get(table) {
        Some(x) => {
            // let vec_lock:RwLock> = *x;
            let read_lock = (*x).read();

            let x1 = spawn(read_lock).wait_future().unwrap();
            //sic!
            let table_vec: Vec = x1.to_vec();

            let bodytext: String = serde_json::to_string(&table_vec).unwrap();
            ApiResult::Ok(bodytext)
        }
        None => ApiResult::Err(
            418,
            "I am a tea pot Error: this table is not allocate - build a bigger restaurant"
                .to_string(),
        ),
    }
}
// Magic tranform of one kind of error to other
fn other(err: E) -> std::io::Error
where
    E: Into>,
{
    std::io::Error::new(std::io::ErrorKind::Other, err)
}

// Magic tranform of one kind of error to other
fn to_stdio_err(e: hyper::Error) -> std::io::Error {
    std::io::Error::new(std::io::ErrorKind::Other, e)
}

enum TeketekeError
where
    E: Into>,
{
    ExternalError(E),
    InternalError(String),
}

fn intoTeketekeError(err: E) -> TeketekeError
where
    E: Into>,
{
    TeketekeError::ExternalError(err)
}

fn teketeke_to_stdio_err(e: TeketekeError) -> std::io::Error {
    match e {
        TeketekeError::ExternalError(err) => err,
        _ => {
            let not_found = std::io::ErrorKind::NotFound;
            std::io::Error::from(not_found)
        }
    }
}

fn table_add_items(
    body: Body,
    table: usize,
) -> Box<
    Future<
            Item = Result>,
            Error = TeketekeError,
        > + Send,
> {
    let res = body
        .concat2()
        .map(move |chunks| {
            serde_json::from_slice::(chunks.as_ref())
                .map(|t| table_store_new_items(table, t.tab))
                .map_err(other)
                .map_err(|e| intoTeketekeError::(e))
                .and_then(|x| {
                    if x == 0 {
                        Err(TeketekeError::InternalError("Nothing modified".to_string()))
                    } else {
                        Ok(x.to_string())
                    }
                })
        })
        .map_err(other)
        .map_err(|e| intoTeketekeError::(e));
    Box::new(res)
}

fn table_remove_item(table: usize, path: String) -> ApiResult {
    let removethis = match path.parse::() {
        Ok(x) => x,
        Err(_x) => return ApiResult::Err(503, "Illegal table number".to_string()),
    };
    let outerlock = STORAGE.read().map(|outer| {
        // range check done is outside
        let innerlock = (*outer).vault(table as usize).write().map(|mut inner| {
            // *inner is now the handle for table vector

            match (*inner).iter().position(|c| (*c).id == removethis) {
                Some(x) => {
                    (*inner).remove(x);
                }
                None => {}
            }
        });
        spawn(innerlock).wait_future()
    });
    match spawn(outerlock).wait_future() {
        Ok(_) => 0,
        Err(_) => 0,
    };
    ApiResult::Ok("".to_string())
}

fn table_store_new_items(table: usize, v: Vec) -> u32 {
    let mut target: Vec = Vec::with_capacity(v.len());
    for i in v {
        target.push(Record {
            itemname: i.itemname,
            id: get_global_num(),
            qty: i.qty,
            state: States::PENDING,
            eta: i.eta,
        })
    }
    let retval = target.len();
    // Get lock for data store
    let outerlock = STORAGE.read().map(|outer| {
        // range check done is outside
        let innerlock = (*outer).vault(table as usize).write().map(|mut inner| {
            (*inner).append(&mut target);
        });
        spawn(innerlock).wait_future()
    });
    match spawn(outerlock).wait_future() {
        Ok(_) => retval as u32,
        Err(_) => 0,
    }
}

fn serve_file(path: &str) -> Box, Error = std::io::Error> + Send> {
    // Only serv the hard coded files needed for this project
    if let Some(cap) = RE_DOWNLOAD_FILE.captures(path) {
        let filename = format!("client/{}", cap.get(1).unwrap().as_str());
        let open_file = File::open(filename);
        let body = open_file.map(|file| {
            let chunks = FileChunkStream::new(file);
            Response::new(Body::wrap_stream(chunks))
        });
        Box::new(body)
    } else {
        let ans = "Thou shalt not read forbidden files";
        let resp = Response::builder()
            .status(403)
            .body(Body::from(ans))
            .unwrap();
        Box::new(future::ok(resp))
    }
}

fn main() {
    let portnum = 8888;
    println!(
        "Starting server port at http://localhost:{}/index.html",
        portnum
    );
    let addr = ((127, 0, 0, 1), portnum).into();

    let server = Server::bind(&addr).serve(|| service_fn(move |req| microservice_handler(req)));

    let server = server.map_err(drop);
    hyper::rt::run(server);
}

#(cfg(test))
mod tests {
    use super::*;

    // TODO/Note add unit test on handler level, when there is time to add
    // a request struct and check the response struct. Have to figure out
    // how to achive this.
    //
    // For now this must be tested at system level by usage.
    #(test)
    fn check_post_ans() {
        let chunks = vec!("hello", " ", "world");
        let stream = futures::stream::iter_ok::<_, ::std::io::Error>(chunks);
        let body = Body::wrap_stream(stream);
        let table: usize = 1;
        let ans = table_add_items(body, table);
        let ans = spawn(ans).wait_future();
        match ans {
            Err(_) => {}
            Ok(_) => assert!(true, "should have failed"),
            _ => assert!(true, "test case took unexpected path"),
        }
        //assert!(r.status() == 422);

        let order = r#"{"tab":({"itemname": "Edamame","qty" : 100 ,"eta":100 },{"itemname": "Nama biru","qty" : 5 ,"eta":200} )}"#;
        let chunks = vec!(order);
        let stream = futures::stream::iter_ok::<_, ::std::io::Error>(chunks);
        let body = Body::wrap_stream(stream);
        let table: usize = 1;
        let ans = table_add_items(body, table);
        let ans = spawn(ans).wait_future();
        match ans {
            Err(_) => assert!(true, "should not have failed"),
            Ok(Ok(x)) => assert_eq!(x, 2.to_string()),
            _ => assert!(true, "test case took unexpected path"),
        }
    }
    #(test)
    fn check_store_values() {
        let mut v: Vec = Vec::new();
        v.push(TableRequest {
            itemname: "Something".to_string(),
            qty: 1,
            eta: 100,
        });

        let table_get_all_res = match table_get_all(10) {
            ApiResult::Ok(x) => x,
            _ => panic!(),
        };
        let before: Vec = serde_json::from_slice(table_get_all_res.as_bytes()).unwrap();
        let storednum = table_store_new_items(10, v);
        assert_eq!(1, storednum);
        let table_get_all_res = match table_get_all(10) {
            ApiResult::Ok(x) => x,
            _ => panic!(),
        };
        let after: Vec = serde_json::from_slice(table_get_all_res.as_bytes()).unwrap();

        // Should be one more entry
        assert!(after.len() - before.len() == 1);
        table_remove_item(10, "1".to_string());

        let table_get_all_res = match table_get_all(10) {
            ApiResult::Ok(x) => x,
            _ => panic!(),
        };
        let _after: Vec = serde_json::from_slice(table_get_all_res.as_bytes()).unwrap();

        //TODO Should be back where we started but item ide can not be guessed as they are world uniq now
        //assert_eq!(after.len(),before.len());
    }

    #(test)
    fn check_regexp() {
        let ans = RE_TABLE_NUM.captures("/table/100");

        match ans {
            Some(m) => {
                assert_eq!(m.get(1).map_or("Unknown", |m| m.as_str()), "100");
            }
            _ => {
                assert!(false);
            }
        }
        match RE_TABLE_NUM.captures("/table/100/open") {
            Some(m) => {
                assert_eq!(m.get(1).map_or("Unknown", |m| m.as_str()), "100");
                assert_eq!(m.get(2).map_or("Unknown", |m| m.as_str()), "/open");
            }
            _ => {
                assert!(false);
            }
        }
    }
}

altcoin – Build a Litecoin fork and have questions

I'm currently following Youtube tutorials (yes many because each one is incomplete in one way or another) to build a Litecoin fork. Up to now, I have been able to make the wallet for my coin on Linux. Awesome. However…

  • In one of the tutorials, the guy suggests, after running the Linux wallet, to use a vm or vps to clone the room (I use a vps – it uses a vm), configure a mycoin. conf file in .mycoin for local machine and vm / vps, then run ./mycoin-qt on both (how am I supposed to run it on a vps terminal?) Supposedly this will allow it 39; extraction. Can anyone clear things up for me? Will I need to start over? This is not the starting knot, is it?

  • How can I make sure that I can extract, for example, 10,000 blocks per minute and then return to its usual settings (say, 20 by 5 minutes initially)? This is so that I can extract a few million blocks for myself. I will also post this on my play site for more transparency.

  • I need help setting up seed nodes. To my knowledge, I'm supposed to have 2. How to configure this (what code should I change, what should I do at each vps)?

  • I am trying to save money. Would it make sense to configure a starting node (or task 1 of this post) on the same server on which I host a DNS server?

  • What's the least stressful way to create a Windows wallet?

  • Thanks in advance. 0.8 Litecoin Fork

    fonts – Can a Pandoc / PDF expert tell me the answer to these three "simple" questions?

    1. Why is Unicode support so important for all these PDF creators? My files in clear, HTML, almost everything use Unicode perfectly, but as soon as I use a single Unicode character when converting to PDF, with Pandoc or any other tool, the whole machine falls broken down and starts to squirt oil and loose screws everywhere.

    2. Why is the actual Courier font not provided when you select "–variable = fontfamily: courier"? Instead, it is a "Courier clone" called "URW Nimbus Mono". Fonts seem to have a lot of strange legal issues for something so widely and commonly used.

    3. Is there a way, instead of specifying & # 39; – variable papersize = "A4" & # 39 ;, & # 39; – variable margin-left = "1.2in" & # 39; and & # 39; – variable margin-top = "1.2in" & # 39 ;, and having to change the last two each time you change the font, I can set the margins to "automatic" by somehow? So that the content pages are always placed evenly in the middle horizontally and vertically for each PDF page?

    Thanks in advance for clarifying these questions.

    select – Questions with Sum Mysql function

    My question is simple, I have a table of sales and another with the types of sales (credit, cash, institutions_associated) which are related to each other, and I have to make a report where to get the total sold by these categories, example: today I sold 100 thousand counted, 300 thousand in credit.

    I do this with:

    SELECT TIP_VTA,SUM(TOT_VTA) FROM VENTAS,TIPVTA WHERE VENTAS.TIP_VTA=TIPVTA.COD_VTA AND FEC_VTA = '2020-02-05' GROUP BY TIP_VTA;
    

    But in the report, all the categories must appear and this query shows them to me only if on the date it actually indicates these types of sales were occupied.

    How could you make a query where all the independent categories appear whether or not they were used on a specific date. Thank you very much in advance.

    ct.category theory – horizontal categorization: two questions

    According to the nlab, horizontal categorization is a process in which a concept is realized as equivalent to a certain type of category with a single object, then this concept is generalized to the same type of categories with an arbitrary number of objects. The prototypical example is the concept of group, which horizontally categorizes the concept of groupoid. It is well known that in some parts of algebraic topology, groupoids are much more practical than groups. Similarly, monoids are categorized into categories, rings into linear categories, etc.

    I have two questions about this. Let C be a concept which horizontally categorizes a concept D.

    1) In many examples, C and D have been known and developed independently of each other. Or at least, D was not introduced as a horizontal categorization of C, but rather this connection was made later. For example, I'm pretty sure that the k-linear categories weren't introduced as a horizontal categorization of k-algebras; instead, they were introduced due to the abundance of examples of (large) k-linear categories that appear in everyday mathematics. Although representation theory seems to be in a current advance from a generalization of k-algebras to small k-linear categories, the concept of a k-linear category was already there before that. Are there examples where D was developed for the purpose of classifying C, let's say to solve some problems which concern C but which cannot be solved with C alone? Maybe categories C * (categorize C * algebras) could provide such an example, but I don't know the history of this concept. And maybe there are other examples too?

    2) In all the examples I know, it is trivial that C has a horizontal categorization and that it is D. Are there more interesting examples where, when you look at C, it doesn & # 39; is not even clear how to interpret C as a category type with an object? I would like to see examples where the connection between C and D is deep and surprising. These examples should illustrate why horizontal categorization is an important and useful concept in practice.

    I could also ask a more provocative question: if a mathematician working outside of category theory reads the nlab article in its current form, why should he even care, because, after all, concepts C and D have already been there without the categorization process?

    webtools – Questions about jSoupLink

    I am trying to use jSoupLink to delete the data. However, I am having trouble using the ParseHTML commamd.

    For example, I cannot make ParseHTML work
    ParseHTML ["https://www.nobelprize.org/nobel_prizes/physics/laureates/1921/einstein-facts.html", "span [itemprop = birthDate]", "text"]

    I would appreciate any help on this as I am new to jSoupLink.

    Questions before my new trip

    I would like to start a new journey in the world of podcasts, but before:

    • How do I rank my podcast website?
    • Can I publish a summary of my audio content?
    • Is there a problem if a blog post talks about different arguments in the same niche?

    Thank you for your time