如何测试字符串输入? (Dyalog APL)

时间:2018-10-30 09:30:29

标签: validation error-handling control-flow apl dyalog

我正在使用此功能Happy来练习控制流程。 Happy测试数字是否为快乐数字。我也在尝试学习错误处理。因此,我尝试捕获用户输入是否为整数以外的其他值。特别是如果输入是字符串。为此,我尝试合并标量测试here,但无法在编辑器上对其进行测试,因为如果尝试输入不带引号的任何字母,我当然会得到一个VALUE ERROR: Undefined name

此外, Mastering APL 本书警告有关使用Quad进行数据输入。

测试输入是否为字符串的正确方法是什么?我假设用户将输入不带引号的字母。

(我正在使用Dyalog APL 17.0)

(我用了有关如何将数字从here拆分成数字的代码?)

Happy
 'Enter a Number'
 N←⎕
 N2←N
 :If N<0
     N←|N
     'You entered'N2
     'Only positive numbers can be happy'
     'We will check if'N'is happy'
     N2←N
 :EndIf
 f←10⊥⍣¯1⊢
 D←f N
 N←+/D×D
 ⍝:If 0≢⊃0⍴⊂N
 ⍝:OrIf N≢⌊N
 ⍝    'You entered: 'N'Enter an integer'
 ⍝    →0
 ⍝:EndIf
 :If N=1
     '***************'
     'Yes'N2'is happy!'
     '***************'
 :Else
     :While N≠1
         N←+/D×D
         D←f N
         N←+/D×D
         'N is:'N
         :If N=4
             '**********************************'
             'Sorry!'N2'is not a happy number'
             '**********************************'
             :Leave
         :EndIf
         :If N=1
             '**********************'
             'Yes!'N2'is a happy number'
             '**********************'
         :EndIf
     :EndWhile
 :EndIf

2 个答案:

答案 0 :(得分:1)

更新后的答案

事不宜迟,这是一个建议的解决方案:

 Happy;ok;N;N2
 'Enter a Number'
 ok←0
 :While ~ok
     N2←N←⍞  ⍝ N2=original input
     ok←∧/N∊⎕D,'¯.'  ⍝ allow high minus for negatives and decimal separator
     (~ok)/'Please enter numeric data!'
 :EndWhile
 N←2⊃⎕VFI N  ⍝ result of ⍞ will be text, so make it numeric
 N←⍬⍴N       ⍝ make it a scalar 
 :If N<0
     N←|N
     'You entered'N2
     'Only positive numbers can be happy'
     'We will check if'N'is happy'
     N2←N
 :EndIf
 f←10⊥⍣¯1⊢
 D←f N
 N←+/D×D

 :If N=1
     '***************'
     'Yes'N2'is happy!'
     '***************'
 :Else
     :While N≠1
         N←+/D×D
         D←f N
         N←+/D×D
         'N is:'N
         :If N=4
             '**********************************'
             'Sorry!'N2'is not a happy number'
             '**********************************'
             :Leave
         :EndIf
         :If N=1
             '**********************'
             'Yes!'N2'is a happy number'
             '**********************'
         :EndIf
     :EndWhile
 :EndIf

备注

  • 勒格兰(Legrand)不使用是正确的,请改用。这为您提供了“未翻译的”字符串,以便您可以使用它。使用系统评估用户输入(没有错误陷阱)可能会打开各种攻击的大门。 (文档here

  • 我使用了⎕VFI(我认为这是Dyalog特定的系统功能)来验证输入。这比更可取,@Override public void onMapReady(MapboxMap mapboxMap) { this.mapboxmap = mapboxMap; mapboxMap.setStyle(Style.OUTDOORS); mapboxMap.getUiSettings().setAttributionEnabled(false); mapboxMap.getUiSettings().setCompassEnabled(true); mapboxMap.getUiSettings().setLogoEnabled(false); mapboxMap.getUiSettings().setRotateGesturesEnabled(true); mapboxMap.getUiSettings().setZoomControlsEnabled(true); initLocationEngine(); initLocationLayer(); } private void initLocationLayer() { /* LocationLayerPlugin locationLayer = new LocationLayerPlugin(mapView, mapboxmap, locationEngine); locationLayer.setRenderMode(RenderMode.GPS);*///(Old Lib Code 0.19.0) LocationComponent locationComponent = mapboxmap.getLocationComponent(); locationComponent.activateLocationComponent(getActivity(), locationEngine); locationComponent.setLocationComponentEnabled(true); locationComponent.setCameraMode(CameraMode.TRACKING); locationComponent.setRenderMode(RenderMode.COMPASS); locationComponent.zoomWhileTracking(30); } @SuppressLint("MissingPermission") private void initLocationEngine() { locationEngine = new LocationEngineProvider(activity).obtainBestLocationEngineAvailable(); locationEngine.setPriority(HIGH_ACCURACY); locationEngine.setInterval(0); locationEngine.setFastestInterval(1000); locationEngine.addLocationEngineListener(this); //userTrackingMode locationEngine.activate(); if (locationEngine.getLastLocation() != null) { Location lastLocation = locationEngine.getLastLocation(); onLocationChanged(lastLocation); currentLocation = Point.fromLngLat(lastLocation.getLongitude(), lastLocation.getLatitude()); } } 可以再次打开门... (文档here]

答案 1 :(得分:1)

您应该使用字符输入documentation)而不是将为您提供用户输入的文字文本。

input←⍞

然后可以对结果使用⎕VFI验证并修正输入documentation)来检查数字输入。它将为您提供两个向量的向量。第一个是布尔值,表示参数中的每个“单词”。第二个向量是数字,每个单词包含一个数字。无效的单词变为零。

(valid values)←⎕VFI input

因此,如果您要查找单个数字,请检查有效性矢量,然后可以检查是否为整数:

:If valid≢,1
:OrIf values≢⌊values
    'You entered: 'N'Enter an integer'
    →0
:EndIf

最后,您可以提取N

N←⊃values

一些不相关的建议

  1. 记住要通过在变量的顶部列出变量来对它们进行本地化,每个变量前面都带有一个;
  2. 在程序的其余部分使用:Else而不是→0,以避免跳转。
  3. 同样,您可以通过将:Leave更改为:EndWhile来避免与:Until N=4一起跳。
  4. 如果您的条件为肯定,则您的代码可能更易于阅读。
  5. 为避免不必要的间距,请连接输出(使用,),而不是将其搁浅(并置)。
  6. 在输出之前加上⎕←,以便更容易发现并提高清晰度。
 Happy;input;valid;values;N;N2;f;D
 ⎕←'Enter a Number'
 input←⍞
 (valid values)←⎕VFI input
 :If valid≡,1
 :AndIf values≡⌊values
     N←⊃values
     N2←N
     :If N<0
         N←|N
         ⎕←'You entered',N2
         ⎕←'Only positive numbers can be happy'
         ⎕←'We will check if',N,'is happy'
         N2←N
     :EndIf
     f←10⊥⍣¯1⊢
     D←f N
     N←+/D×D
     :If N=1
         ⎕←'***************'
         ⎕←'Yes',N2,'is happy!'
         ⎕←'***************'
     :Else
         :While N≠1
             N←+/D×D
             D←f N
             N←+/D×D
             ⎕←'N is:',N
             :If N=4
                 ⎕←'**********************************'
                 ⎕←'Sorry!',N2,'is not a happy number'
                 ⎕←'**********************************'
             :EndIf
             :If N=1
                 ⎕←'**********************'
                 ⎕←'Yes!',N2,'is a happy number'
                 ⎕←'**********************'
             :EndIf
         :Until N=4
     :EndIf
 :Else
     ⎕←'You entered: ',input,' Enter an integer'
 :EndIf