Jump to content

JKSH

Members
  • Posts

    494
  • Joined

  • Last visited

  • Days Won

    36

Posts posted by JKSH

  1. As ak_nz and drjdpowell have both said, it is perfectly fine to implement concrete code in an abstract class. This lets you make full use of inheritance to keep your project tidy and organized.

     

     

    If you come up against scenarios where children are over-riding methods just to inhibit parent behavior then you are definitely seeing a code smell - your hierarchy is making assumptions about behavior that are not true for all children.

    I would say putting common logic in the parent is desirable behavior.   And I don’t mind if some children will want to override the default parent behavior.

     

    "Rules" and "best practices" are established to guide you down a tried-and-true path, to maximize your chances of succeeding the first time you try. However, a set of rules will never cover all possibilities so simply following rules will not guarantee you success.

     

    As the software designer/architect, it is your job to decide whether or not it makes sense to follow a rule in a particular part of your project. Referring to the two quotes above, I'd say: "It's ok to inhibit parent behaviour if 2 out of 20 children need to do it, but not if 18 out of 20 need to do it. If 10 out of 20 need to do it, well... make a judgement call."

     

     

    once I put code in my abstract parent method, is it technically no longer called "abstract"? I can see that it doesn't matter functionally, but I just want to get my terminology right at this early stage. 

     

    I'll answer your question in multiple levels.

     

    Level 1: The definition of "Abstract"

    In OOP, an abstract method is defined as a method which has no implementation. Its purpose is to define an interface for children to follow, and it is the children's job to provide the implementation.

     

    An abstract class is a class that contains one or more abstract methods. An abstract class can contain concrete methods too.

     

    So yes, if you put code in your parent method, then the parent method is concrete, not abstract. However, this in itself doesn't make the parent class non-abstract.

     

     

    Level 2: The (lack of) necessity of "Abstract"

    From your original question, I gather that you're wondering if you need to keep your parent "abstract" in order to abide by some set of best practices, and your latest post suggests that you're no longer worried about this.

     

    To reaffirm: Many examples of inheritance show you an abstract common ancestor implemented by multiple children. However, there are no rules that say you must have an abstract common ancestor. You are free to have a fully concrete (and usable) class as your common ancestor if it makes sense to do so.

     

     

    Level 3: The (lack of the) concept of "Abstract" in LabVIEW

    Since you're interested in formal definitions and terminologies, I'll throw this in: LabVIEW does not support abstract methods in the traditional sense (yet?).

     

    As I said in Level 1, an abstract method has no implementation by definition. However, what people commonly refer to as "abstract VI"s do in fact have an implementation: This implementation simply does nothing. "Having no implementation" is not the same as "Having an implementation that does nothing". LabVIEW doesn't let you create a VI with no implementation.

     

    In other languages, your program cannot be compiled if you inherit from an abstract class but don't provide implementations for all of its abstract methods. This can be a useful way to remind developers to implement them. LabVIEW doesn't do this -- a LabVIEW program will happily run even if you call an "abstract VI". To work around this, what I did in a recent project was to implement pop-up dialogs in my "abstract VIs". This way, I'll get a message at runtime if I forget to implement something in a new child class a few months down the track.

     

    EDIT: LabVIEW programmers fulfil the purpose of abstract functions by doing 2 things: (i) Have a VI that does nothing, and/or (ii) select the "Require descendent classes to override this dynamic dispatch VI" option in the class properties dialog.

     

    See this post for more: http://stackoverflow.com/questions/391483/what-is-the-difference-between-an-abstract-function-and-a-virtual-function (Note that NI explicitly rejected the term "virtual" because it's confusing to talk about non-virtual-Virtual-Instruments, so they picked "dynamic dispatch" instead)

     

    At the end of the day, knowing terminologies is useful (and important!) when discussing concepts, but it shouldn't affect how you design your project.

     

    All the best!

    • Like 1
  2. I therefore contacted the NI-support. The answer I received from there is a case for the cabinet of curiosities (I asked twice and got the same nonsens) but the good news is, they already have a CAR for the issue: 487412.

     

    I prefer to post bug reports to http://forums.ni.com/ -- I seem to get better responses and CARs that way :-D

     

    Also, in the event that it's a PEBCAK (http://en.wiktionary.org/wiki/PEBCAK ) instead of a bug, there will be lots more people who can see my issue and point me in the right direction.

  3. Hi Sharon,

     

    How do you read the text from Excel into LabVIEW?

     

     

    If the excel file texts are either in Japanese or English my string indicator displays the texts without any issues. But I cant display other language texts like korean,turkish or russian.

     

    I'm guessing that the text that you read from Excel text is encoded in SHIFT-JIS.

     

    SHIFT-JIS can encode Japanese and English text, but it cannot encode text from Turkish or Russian languages.

     

    That's why Unicode was invented. Unicode can encode text from many many different languages at the same time.

     

     

     

    I am only trying to read the texts that are to be compared with the OCR output. Before comparison I just want to display the texts that I read from excel file.

     

    To display the text in LabVIEW Unicode mode, you must convert the text into a Unicode encoding first.

     

    As a starting point, read the link I posted earlier (https://decibel.ni.com/content/docs/DOC-10153 ). I haven't tried it yet, but the example under "Converting ASCII Strings to Unicode" should let you display your Japanese text in LabVIEW's Unicode mode.

     

    (I don't think it will correctly convert your Turkish and Russian text, though. But anyway, try it first, and let's do this one step at a time. Text encoding is a moderately complex topic, and you'll probably need a few days to fully understand your problem).

  4. I agree with drdjpowell.

     

    The JSON standard says (emphasis added), "An object is an unordered set of name/value pairs."

     

    This library is standards-compliant and does not need to be changed. The problem lies in the API you're communicating with. Send its developers a bug report and get them to fix it. The world will thank you for it ;)

  5. @jdsommer: Thank you for your detailed and open explanations. Our current project (which doesn't need a wide range of data types)  has been implemented using h5labview, so it looks like I won't be able to try out your toolkit for now. I do agree that high-level convenience APIs make a noticeable difference to a programmer's job.

  6.  

    It's been a long time in coming, but I have completed a new version of the HDF5 Toolkit for LabVIEW that was first released in 2006. The aptly named LVHDF5 Toolkit (version 1.0) is a hefty redesign of the original toolkit (version 0.9) and should solve most of the performance issues with that library while maintaining the flexibility of the the original design.

     

    ...

     

    In particular, I'd like to thank the members of LAVA who worked on xnodes. I've been lurking on the xnode-related pages pages for the past three or four years while slowly building up this revamped toolkit. It would not have been possible without their efforts.

     

    Congratulations on your milestone! Could you tell us more about your toolkit? Your website says, "Several attempts at LabVIEW interfaces to HDF5 have been produced over the years. LVHDF5 is the most complete and flexible interface available". What advantages does it offer over the other attempts, like h5labview? (I notice also that LVHDF5 cannot be co-installed with h5labview

     

     

    I've never heard of the file format but it does sound interesting.  Without knowing much I'd still think TDMS is the better approach if you are going to stay in the NI world.  There are of course features of HDF5 that aren't in TDMS, I just don't know if I would need them.

     

    I work for a systems integrator, so we often need to interface with the non-NI world. HDF5 is a popular format in the scientific community.  In our current project, we had to interface with the client's data logger, which provided us with HDF5 files. Our job was made much easier thanks to 3rd-party LabVIEW bindings.

  7. (I haven't used any of them except h5labview, so I can't give you an assessment on their quality)

     

    If you want a good resource on LabVIEW tricks and designs, I recommend The LabVIEW Style Book by Peter A. Blume. He walks you through sample projects, points out their strengths/weaknesses, and provides lots of useful guidelines.

    • Like 1
  8. My opinion: VIs should be called VIs when not in the context of an application or hierarchy.  I think that referring to VIs in general as subVIs is incorrect and would argue for re-education of the confused.

    +1. Calling something "sub" when it's not sub-anything feels silly to me. On the other hand, reeducation sounds like an uphill battle.

     

    For an alternative: How does "Child VI" sound?

     

     

    I think most people would disagree with me, but I think of it like this... it feels to me as though a VI is only something where the UI is intended to be used (even if just as a dialog or debug screen). Anything else, which is intended to always be called by something else with a UI is a subVI, function, or subroutine.

    This makes sense too, actually -- VIs are "Virtual Instruments" after all, and were originally designed to be software versions of hardware instruments.

     

     

    The root cause of AQ's problem is that people don't think about the meaning of the name "subVI". But on a related note, the name "VI" itself is extremely overloaded. VIs started off as Virtual Instruments, but have since expanded to become all kinds of things. SubVIs, Polymorphic VIs, Global VIs, Control VIs, XControl Method VIs have very little to do with instruments. So now we have a construct whose name is "Virtual Instrument" but whose meaning is "One of several forms of LabVIEW code"

  9. The HEX time is in milliseconds and the day of my time was 4 sept 2014.

     

    This is actually a responce from a controller and if i subtract two values i get difference in milliseconds.

    Milliseconds relative to what?

    • Relative to the time when the controller started running?
    • Relative to midnight of 1 January 1970?
    • Something else?

     

    0x0F2E3B2D is 254688045 in decimal. 254688045 milliseconds is about 8.8 hours.

     

    Had your controller been running for 8.8 hours when you captured that timestamp?

  10. Hi,

     

    What I want to do now is remove the enum, and make it a class. (it is my understanding that have type-defined controls inside a class can lead to some weirdness).

     

    It sounds like the primary problem that you want to solve is the problem of a misbehaving IDE, and you have chosen LVOOP as your mechanism for working around that problem. Is this correct?

     

    Some good questions to ask yourself are:

    1. From your primary problem's point of view: Will replacing enums with classes make your IDE problem go away, without introducing new IDE problems?
    2. From an architectural point of view: Which approach feels more sensible to you -- your existing enum-based system, or your proposed class-based system?

     

    So I figure I create a mode class (and child classes corresponding to the different modes my instrument can be in), and then at run-time change this object. Each of these mode child classes would implement a Read function, and they would know exactly how many bytes to read for their specific mode. This seems a bit weird as I would be implementing the Read function in the Mode class which does not feel like the right place to put it. Alternatively I can implement a BytesToRead function in each of the Mode classes and then also a Parse method. 

     

    I agree that your first proposal feels weird: a "Mode" sounds like it should contain config information and parameters, but it shouldn't perform any actions itself. Thus, I'm also not convinced that the Parse method belongs in the Mode class. (Of course, this is also a matter of taste -- I'm sure there are others who are happy to use this approach)

     

    Having each Mode subclass report BytesToRead back to the caller sounds quite reasonable, but only if every current and future Instrument subclass is expected to read the same number of bytes for a particular Mode. (Would there be any cases where different Instruments read a different number of bytes for the same Mode?)

  11. Hi John,
     
    Are you designing a generic framework, or a specific application?
     

     

    If Actor A has a message (that in turns calls a method in Actor A) to create an instance of Actor B, then adding Actor A to a project create a static dependency on Actor B.  This makes it impossible to test Actor A in isolation with a test harness.  The recent VI Shots episode about AOP discussed the need to isolate Actors so they could be built and tested as independent 'actors'.  If Actor B also has the ability to launch Actor C, then Actor C also becomes a dependency of Actor A.  And if Actor B sends a message to Actor A, then the static link to that message (required to construct it) will create a dependency on Actor A for Actor B.  So, the end result is adding any actor in your project to another project loads the entire hierarchy of actors into memory as a dependency and makes testing anything in isolation impossible.

     

    A static dependency doesn't necessarily preclude testing in isolation.

     

    Let's say we have 2 classes (A and B), where some of Class A's actions involve launching an instance of B and exchanging messages with it. Your unit tests could look something like this:

    • Class B testing:
      1. Launch an instance of Class B from a top-level VI
      2. Let your top-level VI send a variety of messages to your B instance, and check that it reacts appropriately
    • Class A testing:
      1. Launch an instant of Class A from a top-level VI
      2. Let your top-level VI send a variety of messages to your B instance, and check that it reacts appropriately

    (For even better isolation, launch a new instance for every message tested)

     

    Yes, the Class A tests will also cause Class B to be loaded and launched, but your test harness for Class A doesn't know that Class B is involved at all. Some might classify the Class A test as an Integration test rather than a Unit test, but the bottom line is that you can still treat Class A as an isolated black box.

  12. Hi Tom,

     

    Does it help if you call TDMS Flush.vi after you write the property?

     

     

    Sharing a single reference would solve this particular problem.  It would also add more messaging overhead.  The process that closes the reference would have to notify the other processes and wait for acknowledges before it could safely close the reference.  Otherwise another process could attempt to access the TDMS file with a bad reference.  

     

    To avoid race conditions, you'd need some form of messaging/synchronization anyway: You need to ensure that your Read VI waits for your Write VI to finish writing the property first, before it tries to read it.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.