我正在完成真实世界Haskell。在本章中,作者解释了如何使用EAN13编码实现条码识别。
我复制了这本书在我的回购书中摘录。的大部分代码,当我最终到达检查我的300多行代码是否像预期的那样工作时,我得到了一个坏消息:
-- Finding the Correct Sequence
*Main> let input = zip (runLengths $ encodeEAN13 "9780132114677") (cycle [Zero, One])
*Main> listToMaybe . solve . candidateDigits $ input
Just [0,2,0,1,0,0,0,0,0,0,0,0,1] -- WRONG Actual
Just [9,7,8,0,1,3,2,1,1,4,6,7,7] -- Expected
自从这本书出版以来,我注意到一些类型的签名发生了变化,例如:
$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> import qualified Data.Map as M
Prelude M> :t M.lookup
M.lookup :: Ord k => k -> M.Map k a -> Maybe a
-- in the book: M.lookup :: (Ord k, Monad m) => k -> M.Map k a -> m a
我试着在GHCi中复制每一个例子,除了最后一个例子,我总是得到与这本书相同的结果。
有谁从这本书中提到过这个话题??
作者并没有解释每一行代码,特别是input
变量没有在任何地方定义let input = zip (runLengths $ encodeEAN13 "9780132114677") (cycle [Zero, One])
。
一些EAN13编码的条形码用于测试?
如果没有人知道这本书,您会有一些EAN13编码条形码的样本,例如:
*Main M> encodeEAN13 "9780132114677"
"101011101100010010100111001100101000010101011011001100110110011010111001010000100010010001001010000101"
以确保我对函数的测试是正确的?
先谢谢你
发布于 2017-10-21 08:11:53
您的实现中有两个bug:
首先,在encodeDigits
中,您已经编写了splitAt 5
,而它应该是splitAt 6
。这修复了@注意到的编码错误。
其次,在bestScores
中,您已经编写了:
[(distance d (scaleToOne ps), n) | d <- srl, n <- digits]
当你应该写:
zip [distance d (scaleToOne ps) | d <- srl] digits
这修复了你的解码错误。
我希望我可以说我使用了我的超人调试技能来发现这些but,但我碰巧有我自己的Barcode.hs
副本,从几年前我自己做第12章开始。
发布于 2017-10-20 02:00:54
看上去你的1和0的顺序有三个问题,第一个是你的AEAN-13中心代码似乎在覆盖你第六个角色的开头。它真的应该在B的地方。你有一个额外的4个零和一个额外的结束标记加到你的序列的末尾。
下面是一个生成校验和并列出1和0的工具:
var arrayCodeEANBin, arrayStructEAN;
arrayCodeEANBin = [ [ '0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011' ], [ '0100111', '0110011', '0011011', '0100001', '0011101', '0111001', '0000101', '0010001', '0001001', '0010111' ], [ '1110010', '1100110', '1101100', '1000010', '1011100', '1001110', '1010000', '1000100', '1001000', '1110100' ] ];
arrayStructEAN = ['000000', '001011', '001101', '001110', '010011', '011001', '011100', '010101', '010110', '011010']
var strRaw = "";
var strText = "";
function funcEAN() { // EAN-13
var intSumOdd = 0, intSumEven = 0, intCheck, i, j, strStruct;
// Compute check digit and add it to raw string
for (i = 0; i < 12; i += 2) {
intSumEven += parseInt(strText[i]);
intSumOdd += parseInt(strText[i+1]);
}
intCheck = ((intSumOdd * 3) + intSumEven) % 10;
if (intCheck > 0) {
intCheck = 10 - intCheck;
}
strText += intCheck;
// Converts Code EAN array into string of 1's and 0's
strRaw = "101"
// First six bar sequences
for (i = 1; i < 7; i += 1) {
strStruct = arrayStructEAN[strText[0]];
strRaw += arrayCodeEANBin[strStruct[i-1]][strText[i]];
}
// Middle sequence
strRaw += "01010";
// Last six bar sequences, including check digit
for (i = 0; i < 6; i += 1) {
strRaw += arrayCodeEANBin[2][strText[i+7]];
}
strRaw += "101";
} // End EAN-13
var buttonBarcode = document.getElementById("btnGenBar");
buttonBarcode.onclick = function () {
strText = document.getElementById("textBarcode").value;
funcEAN();
document.getElementById("textRaw").value = strRaw;
document.getElementById("textRaw").select();
}
<head>
<title>EAN-13 Barcodes in vanilla JavaScript</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<body>
<div id="inputForm">
Enter Text: <input type="text" id="textBarcode" tabindex=1/>
<input type="button" id="btnGenBar" value="Gen 1's and 0's" tabindex=4/>
</div>
<p></p>
<div id="result"></div>
<p></p>
<textarea rows="3" cols="110" id="textRaw" tabindex=0></textarea>
<script type="text/javascript" src="./SO_JS-EAN-13.js"></script>
</body>
</html>
如果您想看到实际生成的条形码,我有一个码页。它不添加格式化文本,但条形码扫描。
https://stackoverflow.com/questions/46825859
复制