How to make a check like in kivy?












-4














I don’t understand how to do assignment checking to a variable, as it is done in Kivy.
I know how this is done for class properties, and it looks like this



#!/usr/bin/python3.6    
class Foo:
var = property()
def __init__(self):
self._var = 0
@var.setter
def var(self, value):
self._var = value
# code setter
pass

@var.getter
def var(self):
# code getter
print('Getter method')
return self._var

a = Foo()
a.var = 5
print(a.var)
# Getter method
# 5


In Kivy can do:



class LabelBase(Label):
msg = StringProperty('t')

def __init__(self, **kwargs):
super(LabelBase, self).__init__(**kwargs)
self.msg = 5


I take



     Traceback (most recent call last):
File "/home/Python/Prj/View/Main.py", line 83, in <module>
Start().build()
File "/home/Python/Prj/View/Main.py", line 73, in build
GUI().run()
File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
root = self.build()
File "/home/Python/Prj/View/Main.py", line 65, in build
main_window = MainFrame()
File "/home/Python/Prj/View/Main.py", line 52, in __init__
self.label = LabelBase(text='test')
File "/home/Python/Prj/View/Main.py", line 16, in __init__
self.msg = 5
File "kivy/properties.pyx", line 483, in
kivy.properties.Property.__set__
File "kivy/properties.pyx", line 521, in kivy.properties.Property.set
File "kivy/properties.pyx", line 512, in kivy.properties.Property.set
File "kivy/properties.pyx", line 678, in
kivy.properties.StringProperty.check
ValueError: LabelBase.msg accept only str


Renamed the question because it did not correspond to what was happening










share|improve this question




















  • 1




    Assignment isn't a method.
    – PM 2Ring
    Nov 23 '18 at 8:32












  • Good, how was it done team Kivy?
    – Shatten
    Nov 23 '18 at 8:34








  • 1




    I doubt very much that this is possible even in Kivy. Please show an example where you do that.
    – Daniel Roseman
    Nov 23 '18 at 8:36








  • 2




    But isn't that exactly the same as what you have in your first snippet above, with getter and setter methods? It's not at all what you do in the second, where you try and reassign the whole object.
    – Daniel Roseman
    Nov 23 '18 at 8:41






  • 1




    Okay after reading the source code I understand what they're doing, so what is it exactly that you want? Because what kivy is doing and what you're asking to do (claiming that kivy does it) are completely different.
    – SilverSlash
    Nov 23 '18 at 9:44
















-4














I don’t understand how to do assignment checking to a variable, as it is done in Kivy.
I know how this is done for class properties, and it looks like this



#!/usr/bin/python3.6    
class Foo:
var = property()
def __init__(self):
self._var = 0
@var.setter
def var(self, value):
self._var = value
# code setter
pass

@var.getter
def var(self):
# code getter
print('Getter method')
return self._var

a = Foo()
a.var = 5
print(a.var)
# Getter method
# 5


In Kivy can do:



class LabelBase(Label):
msg = StringProperty('t')

def __init__(self, **kwargs):
super(LabelBase, self).__init__(**kwargs)
self.msg = 5


I take



     Traceback (most recent call last):
File "/home/Python/Prj/View/Main.py", line 83, in <module>
Start().build()
File "/home/Python/Prj/View/Main.py", line 73, in build
GUI().run()
File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
root = self.build()
File "/home/Python/Prj/View/Main.py", line 65, in build
main_window = MainFrame()
File "/home/Python/Prj/View/Main.py", line 52, in __init__
self.label = LabelBase(text='test')
File "/home/Python/Prj/View/Main.py", line 16, in __init__
self.msg = 5
File "kivy/properties.pyx", line 483, in
kivy.properties.Property.__set__
File "kivy/properties.pyx", line 521, in kivy.properties.Property.set
File "kivy/properties.pyx", line 512, in kivy.properties.Property.set
File "kivy/properties.pyx", line 678, in
kivy.properties.StringProperty.check
ValueError: LabelBase.msg accept only str


Renamed the question because it did not correspond to what was happening










share|improve this question




















  • 1




    Assignment isn't a method.
    – PM 2Ring
    Nov 23 '18 at 8:32












  • Good, how was it done team Kivy?
    – Shatten
    Nov 23 '18 at 8:34








  • 1




    I doubt very much that this is possible even in Kivy. Please show an example where you do that.
    – Daniel Roseman
    Nov 23 '18 at 8:36








  • 2




    But isn't that exactly the same as what you have in your first snippet above, with getter and setter methods? It's not at all what you do in the second, where you try and reassign the whole object.
    – Daniel Roseman
    Nov 23 '18 at 8:41






  • 1




    Okay after reading the source code I understand what they're doing, so what is it exactly that you want? Because what kivy is doing and what you're asking to do (claiming that kivy does it) are completely different.
    – SilverSlash
    Nov 23 '18 at 9:44














-4












-4








-4







I don’t understand how to do assignment checking to a variable, as it is done in Kivy.
I know how this is done for class properties, and it looks like this



#!/usr/bin/python3.6    
class Foo:
var = property()
def __init__(self):
self._var = 0
@var.setter
def var(self, value):
self._var = value
# code setter
pass

@var.getter
def var(self):
# code getter
print('Getter method')
return self._var

a = Foo()
a.var = 5
print(a.var)
# Getter method
# 5


In Kivy can do:



class LabelBase(Label):
msg = StringProperty('t')

def __init__(self, **kwargs):
super(LabelBase, self).__init__(**kwargs)
self.msg = 5


I take



     Traceback (most recent call last):
File "/home/Python/Prj/View/Main.py", line 83, in <module>
Start().build()
File "/home/Python/Prj/View/Main.py", line 73, in build
GUI().run()
File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
root = self.build()
File "/home/Python/Prj/View/Main.py", line 65, in build
main_window = MainFrame()
File "/home/Python/Prj/View/Main.py", line 52, in __init__
self.label = LabelBase(text='test')
File "/home/Python/Prj/View/Main.py", line 16, in __init__
self.msg = 5
File "kivy/properties.pyx", line 483, in
kivy.properties.Property.__set__
File "kivy/properties.pyx", line 521, in kivy.properties.Property.set
File "kivy/properties.pyx", line 512, in kivy.properties.Property.set
File "kivy/properties.pyx", line 678, in
kivy.properties.StringProperty.check
ValueError: LabelBase.msg accept only str


Renamed the question because it did not correspond to what was happening










share|improve this question















I don’t understand how to do assignment checking to a variable, as it is done in Kivy.
I know how this is done for class properties, and it looks like this



#!/usr/bin/python3.6    
class Foo:
var = property()
def __init__(self):
self._var = 0
@var.setter
def var(self, value):
self._var = value
# code setter
pass

@var.getter
def var(self):
# code getter
print('Getter method')
return self._var

a = Foo()
a.var = 5
print(a.var)
# Getter method
# 5


In Kivy can do:



class LabelBase(Label):
msg = StringProperty('t')

def __init__(self, **kwargs):
super(LabelBase, self).__init__(**kwargs)
self.msg = 5


I take



     Traceback (most recent call last):
File "/home/Python/Prj/View/Main.py", line 83, in <module>
Start().build()
File "/home/Python/Prj/View/Main.py", line 73, in build
GUI().run()
File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
root = self.build()
File "/home/Python/Prj/View/Main.py", line 65, in build
main_window = MainFrame()
File "/home/Python/Prj/View/Main.py", line 52, in __init__
self.label = LabelBase(text='test')
File "/home/Python/Prj/View/Main.py", line 16, in __init__
self.msg = 5
File "kivy/properties.pyx", line 483, in
kivy.properties.Property.__set__
File "kivy/properties.pyx", line 521, in kivy.properties.Property.set
File "kivy/properties.pyx", line 512, in kivy.properties.Property.set
File "kivy/properties.pyx", line 678, in
kivy.properties.StringProperty.check
ValueError: LabelBase.msg accept only str


Renamed the question because it did not correspond to what was happening







python kivy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 11:02

























asked Nov 23 '18 at 8:26









Shatten

33




33








  • 1




    Assignment isn't a method.
    – PM 2Ring
    Nov 23 '18 at 8:32












  • Good, how was it done team Kivy?
    – Shatten
    Nov 23 '18 at 8:34








  • 1




    I doubt very much that this is possible even in Kivy. Please show an example where you do that.
    – Daniel Roseman
    Nov 23 '18 at 8:36








  • 2




    But isn't that exactly the same as what you have in your first snippet above, with getter and setter methods? It's not at all what you do in the second, where you try and reassign the whole object.
    – Daniel Roseman
    Nov 23 '18 at 8:41






  • 1




    Okay after reading the source code I understand what they're doing, so what is it exactly that you want? Because what kivy is doing and what you're asking to do (claiming that kivy does it) are completely different.
    – SilverSlash
    Nov 23 '18 at 9:44














  • 1




    Assignment isn't a method.
    – PM 2Ring
    Nov 23 '18 at 8:32












  • Good, how was it done team Kivy?
    – Shatten
    Nov 23 '18 at 8:34








  • 1




    I doubt very much that this is possible even in Kivy. Please show an example where you do that.
    – Daniel Roseman
    Nov 23 '18 at 8:36








  • 2




    But isn't that exactly the same as what you have in your first snippet above, with getter and setter methods? It's not at all what you do in the second, where you try and reassign the whole object.
    – Daniel Roseman
    Nov 23 '18 at 8:41






  • 1




    Okay after reading the source code I understand what they're doing, so what is it exactly that you want? Because what kivy is doing and what you're asking to do (claiming that kivy does it) are completely different.
    – SilverSlash
    Nov 23 '18 at 9:44








1




1




Assignment isn't a method.
– PM 2Ring
Nov 23 '18 at 8:32






Assignment isn't a method.
– PM 2Ring
Nov 23 '18 at 8:32














Good, how was it done team Kivy?
– Shatten
Nov 23 '18 at 8:34






Good, how was it done team Kivy?
– Shatten
Nov 23 '18 at 8:34






1




1




I doubt very much that this is possible even in Kivy. Please show an example where you do that.
– Daniel Roseman
Nov 23 '18 at 8:36






I doubt very much that this is possible even in Kivy. Please show an example where you do that.
– Daniel Roseman
Nov 23 '18 at 8:36






2




2




But isn't that exactly the same as what you have in your first snippet above, with getter and setter methods? It's not at all what you do in the second, where you try and reassign the whole object.
– Daniel Roseman
Nov 23 '18 at 8:41




But isn't that exactly the same as what you have in your first snippet above, with getter and setter methods? It's not at all what you do in the second, where you try and reassign the whole object.
– Daniel Roseman
Nov 23 '18 at 8:41




1




1




Okay after reading the source code I understand what they're doing, so what is it exactly that you want? Because what kivy is doing and what you're asking to do (claiming that kivy does it) are completely different.
– SilverSlash
Nov 23 '18 at 9:44




Okay after reading the source code I understand what they're doing, so what is it exactly that you want? Because what kivy is doing and what you're asking to do (claiming that kivy does it) are completely different.
– SilverSlash
Nov 23 '18 at 9:44












2 Answers
2






active

oldest

votes


















0














I assume you want to do some checks on assignments, like type checking in the kivy case. Your example looks to me very unidiomatic, I'd write it the following way:



class Foo:

@property
def var(self):
return self._var

@var.setter
def var(self, value):
if type(value) == str:
self._var = value


How does it work? Actually it's a bit complicated, but here is a good ressource. property returns a descriptor which basically means that foo.var = x is translated to foo.var.__set__(x) (which then calls something "equivalent" to Foo.var.setter_function(foo, x)). It just says "instead of storing an assigned value, call this function".



How is the kivy case different? Assume we have the following class:



class Bar(Widget):
var = StringProperty()


The behavior is very similar to the python code before, but the setter and getter methods are defined by kivy and not here in the class. But if you assign a value to a Bar instance bar.var = x a setter is called bar.var.__set__(x). The setter does not only check for types but also emits events if the value changed.



You can also create properties with getters and setters already provided by implementing a descriptor. You need to implement __set__ and __get__:



class MyStringProperty:

def __init__(self, default):
self._default = default

def __set__(self, instance, value):
if type(value) == str:
instance._value = value

def __get__(self, instance, owner):
return getattr(instance, "_value", self._default)

class Foo:
var = MyStringProperty("x")

foo = Foo()
print(foo.var)
foo.var = 3
print(foo.var)
foo.var = "asdf"
print(foo.var)


(The documentation speaks from get, set, delete and set_name, but I think in the common case one can get away with only implementing set and get.)






share|improve this answer





















  • I'm understood, thank you!
    – Shatten
    Nov 26 '18 at 3:34



















0














If you want to check the value, you simply add check code to your setter. For example, if you want var to be limited to int or float, you can modify your setter as:



   @var.setter
def var(self, value):
if type(value) not in (int, float):
raise ValueError('%s.%s accept only int or float (got %r)' % (
self.__class__.__name__,
'var', value))
self._var = value


This code is a slight modification of Kivy check code.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53442997%2fhow-to-make-a-check-like-in-kivy%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I assume you want to do some checks on assignments, like type checking in the kivy case. Your example looks to me very unidiomatic, I'd write it the following way:



    class Foo:

    @property
    def var(self):
    return self._var

    @var.setter
    def var(self, value):
    if type(value) == str:
    self._var = value


    How does it work? Actually it's a bit complicated, but here is a good ressource. property returns a descriptor which basically means that foo.var = x is translated to foo.var.__set__(x) (which then calls something "equivalent" to Foo.var.setter_function(foo, x)). It just says "instead of storing an assigned value, call this function".



    How is the kivy case different? Assume we have the following class:



    class Bar(Widget):
    var = StringProperty()


    The behavior is very similar to the python code before, but the setter and getter methods are defined by kivy and not here in the class. But if you assign a value to a Bar instance bar.var = x a setter is called bar.var.__set__(x). The setter does not only check for types but also emits events if the value changed.



    You can also create properties with getters and setters already provided by implementing a descriptor. You need to implement __set__ and __get__:



    class MyStringProperty:

    def __init__(self, default):
    self._default = default

    def __set__(self, instance, value):
    if type(value) == str:
    instance._value = value

    def __get__(self, instance, owner):
    return getattr(instance, "_value", self._default)

    class Foo:
    var = MyStringProperty("x")

    foo = Foo()
    print(foo.var)
    foo.var = 3
    print(foo.var)
    foo.var = "asdf"
    print(foo.var)


    (The documentation speaks from get, set, delete and set_name, but I think in the common case one can get away with only implementing set and get.)






    share|improve this answer





















    • I'm understood, thank you!
      – Shatten
      Nov 26 '18 at 3:34
















    0














    I assume you want to do some checks on assignments, like type checking in the kivy case. Your example looks to me very unidiomatic, I'd write it the following way:



    class Foo:

    @property
    def var(self):
    return self._var

    @var.setter
    def var(self, value):
    if type(value) == str:
    self._var = value


    How does it work? Actually it's a bit complicated, but here is a good ressource. property returns a descriptor which basically means that foo.var = x is translated to foo.var.__set__(x) (which then calls something "equivalent" to Foo.var.setter_function(foo, x)). It just says "instead of storing an assigned value, call this function".



    How is the kivy case different? Assume we have the following class:



    class Bar(Widget):
    var = StringProperty()


    The behavior is very similar to the python code before, but the setter and getter methods are defined by kivy and not here in the class. But if you assign a value to a Bar instance bar.var = x a setter is called bar.var.__set__(x). The setter does not only check for types but also emits events if the value changed.



    You can also create properties with getters and setters already provided by implementing a descriptor. You need to implement __set__ and __get__:



    class MyStringProperty:

    def __init__(self, default):
    self._default = default

    def __set__(self, instance, value):
    if type(value) == str:
    instance._value = value

    def __get__(self, instance, owner):
    return getattr(instance, "_value", self._default)

    class Foo:
    var = MyStringProperty("x")

    foo = Foo()
    print(foo.var)
    foo.var = 3
    print(foo.var)
    foo.var = "asdf"
    print(foo.var)


    (The documentation speaks from get, set, delete and set_name, but I think in the common case one can get away with only implementing set and get.)






    share|improve this answer





















    • I'm understood, thank you!
      – Shatten
      Nov 26 '18 at 3:34














    0












    0








    0






    I assume you want to do some checks on assignments, like type checking in the kivy case. Your example looks to me very unidiomatic, I'd write it the following way:



    class Foo:

    @property
    def var(self):
    return self._var

    @var.setter
    def var(self, value):
    if type(value) == str:
    self._var = value


    How does it work? Actually it's a bit complicated, but here is a good ressource. property returns a descriptor which basically means that foo.var = x is translated to foo.var.__set__(x) (which then calls something "equivalent" to Foo.var.setter_function(foo, x)). It just says "instead of storing an assigned value, call this function".



    How is the kivy case different? Assume we have the following class:



    class Bar(Widget):
    var = StringProperty()


    The behavior is very similar to the python code before, but the setter and getter methods are defined by kivy and not here in the class. But if you assign a value to a Bar instance bar.var = x a setter is called bar.var.__set__(x). The setter does not only check for types but also emits events if the value changed.



    You can also create properties with getters and setters already provided by implementing a descriptor. You need to implement __set__ and __get__:



    class MyStringProperty:

    def __init__(self, default):
    self._default = default

    def __set__(self, instance, value):
    if type(value) == str:
    instance._value = value

    def __get__(self, instance, owner):
    return getattr(instance, "_value", self._default)

    class Foo:
    var = MyStringProperty("x")

    foo = Foo()
    print(foo.var)
    foo.var = 3
    print(foo.var)
    foo.var = "asdf"
    print(foo.var)


    (The documentation speaks from get, set, delete and set_name, but I think in the common case one can get away with only implementing set and get.)






    share|improve this answer












    I assume you want to do some checks on assignments, like type checking in the kivy case. Your example looks to me very unidiomatic, I'd write it the following way:



    class Foo:

    @property
    def var(self):
    return self._var

    @var.setter
    def var(self, value):
    if type(value) == str:
    self._var = value


    How does it work? Actually it's a bit complicated, but here is a good ressource. property returns a descriptor which basically means that foo.var = x is translated to foo.var.__set__(x) (which then calls something "equivalent" to Foo.var.setter_function(foo, x)). It just says "instead of storing an assigned value, call this function".



    How is the kivy case different? Assume we have the following class:



    class Bar(Widget):
    var = StringProperty()


    The behavior is very similar to the python code before, but the setter and getter methods are defined by kivy and not here in the class. But if you assign a value to a Bar instance bar.var = x a setter is called bar.var.__set__(x). The setter does not only check for types but also emits events if the value changed.



    You can also create properties with getters and setters already provided by implementing a descriptor. You need to implement __set__ and __get__:



    class MyStringProperty:

    def __init__(self, default):
    self._default = default

    def __set__(self, instance, value):
    if type(value) == str:
    instance._value = value

    def __get__(self, instance, owner):
    return getattr(instance, "_value", self._default)

    class Foo:
    var = MyStringProperty("x")

    foo = Foo()
    print(foo.var)
    foo.var = 3
    print(foo.var)
    foo.var = "asdf"
    print(foo.var)


    (The documentation speaks from get, set, delete and set_name, but I think in the common case one can get away with only implementing set and get.)







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 23 '18 at 15:43









    syntonym

    4,43621337




    4,43621337












    • I'm understood, thank you!
      – Shatten
      Nov 26 '18 at 3:34


















    • I'm understood, thank you!
      – Shatten
      Nov 26 '18 at 3:34
















    I'm understood, thank you!
    – Shatten
    Nov 26 '18 at 3:34




    I'm understood, thank you!
    – Shatten
    Nov 26 '18 at 3:34













    0














    If you want to check the value, you simply add check code to your setter. For example, if you want var to be limited to int or float, you can modify your setter as:



       @var.setter
    def var(self, value):
    if type(value) not in (int, float):
    raise ValueError('%s.%s accept only int or float (got %r)' % (
    self.__class__.__name__,
    'var', value))
    self._var = value


    This code is a slight modification of Kivy check code.






    share|improve this answer


























      0














      If you want to check the value, you simply add check code to your setter. For example, if you want var to be limited to int or float, you can modify your setter as:



         @var.setter
      def var(self, value):
      if type(value) not in (int, float):
      raise ValueError('%s.%s accept only int or float (got %r)' % (
      self.__class__.__name__,
      'var', value))
      self._var = value


      This code is a slight modification of Kivy check code.






      share|improve this answer
























        0












        0








        0






        If you want to check the value, you simply add check code to your setter. For example, if you want var to be limited to int or float, you can modify your setter as:



           @var.setter
        def var(self, value):
        if type(value) not in (int, float):
        raise ValueError('%s.%s accept only int or float (got %r)' % (
        self.__class__.__name__,
        'var', value))
        self._var = value


        This code is a slight modification of Kivy check code.






        share|improve this answer












        If you want to check the value, you simply add check code to your setter. For example, if you want var to be limited to int or float, you can modify your setter as:



           @var.setter
        def var(self, value):
        if type(value) not in (int, float):
        raise ValueError('%s.%s accept only int or float (got %r)' % (
        self.__class__.__name__,
        'var', value))
        self._var = value


        This code is a slight modification of Kivy check code.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 15:35









        John Anderson

        2,5131413




        2,5131413






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53442997%2fhow-to-make-a-check-like-in-kivy%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            Alexandru Averescu

            Trompette piccolo