• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

Koren

Member
Apparently, you tried to print the object?

If your object is printable, you should define in the class a methode __repr__() and/or a method __str__() that return the string to be printed...

print() call __str__(), but if __str__() isn't available, it fallback on __repr__() (without entering too much into details).

__str__() should be human-readable, __repr__() a way to represent the object by a string (for example, for saving the object in a text file) with the idea of converting back the string into an object...

I'll give you an example in two minutes...

Edit:

With this definition of the class
Code:
class ctest :
    def __init__(self, value=None) :
        self.value = value
we get this behavior:
Code:
In [1]: test = ctest(42)

In [2]: print(test)
<__main__.ctest object at 0x07716E90>

With this one:
Code:
class ctest :
    def __init__(self, value=None) :
        self.value = value

    def __str__(self) :
        return "the value is "+str(self.value)

we get:
Code:
In [3]: test = ctest(42)

In [4]: print(test)
the value is 42

Is this what you're after?


Re-edit: to be clear, once you've done this, you just have to do
Code:
def displayPokemons(pokemon_list) :
    for poke in Pokemon :
        print(poke)
for example...


Re-re-edit:

Of course, Python give unlimited access to everything, so you don't NEED to use __str__.

You coud do
Code:
def displayPokemons(pokemon_list) :
    for poke in Pokemon :
        print("Name:", poke.name)
        print("Ability:", poke.ability)

But since it's a attempt to see how classes work, I'd say using some special methods would probably be interesting... (?)

Re-re-re-edit :

Or
Code:
def displayPokemons(pokemon_list) :
    for poke in Pokemon :
        print("Name:", poke.Get_Name() )
        print("Ability:", poke.Get_Ability() )
since you've declared those two functions.

Though I'd say that getters are unpythonic, you shouldn't write Get_XXX methods. That's inherited from other languages like Java or C++, but that doesn't make sense in Python.
 

Gurrry

Member
Is this what you're after?

This does seem to be what im after, however, some of these examples arent looking familiar to me. Im thinking what I need to do is even more simple than this. However, I think youre spot on about trying to print the object, because that is the same looking "error" that I get each time.

What I dont get is why I cant get the list to print out what has been appended to it like I have in the past. I should be able to just say print(pokemon_list[0]), right?
 

Gurrry

Member
Ok, so after trying your re-re-edit, ive got it to finally recognize the list and print out the pokemon and abilites that the user enters, but its also printing out that hexadecimal thing as well.

Im sure i just need to clean up the code a bit. I think my problem when I tried the for loops that I did originally was that i wasnt using dot notation and calling .name or .ability.

Thank you for the quick response. This helped alot. I thought I was understanding classes and stuff but this has made me rethink everything. I need to find a good tutorial to teach me because I really just dont gel well with the way our professor teaches this stuff.

edit: Also, whats even dumber is that this is a pre-requisite class that teaches python, then in the next class, they switch to C++. Like who the fuck thought that up? Get all these beginners started on python and then switch over into a completely different language with 0 exposure to it. Brilliant stuff.
 

Koren

Member
This does seem to be what im after, however, some of these examples arent looking familiar to me. Im thinking what I need to do is even more simple than this.
Check the edits, if you haven't because I've added more "straightforward" solutions.

The one before the last may be what you're after.

What I dont get is why I cant get the list to print out what has been appended to it like I have in the past. I should be able to just say print(pokemon_list[0]), right?
The list contains "Pokemon" objects. When you try to print the list, or when you try to print an element, like pokemon_list[0], Python try to display/print the object...

Unfortunately, he doesn't have a clue on how you would like this to appear, so the only thing it displays is the type (__main__.Pokemon object, an "object from the Pokemon class defined in the __main__ namespace) and the address in the memory.

Python can display all usual objects because they have a __str__ or a __repr__ method (or something equivalent)

For example, integers class int have (kinda) a __repr__ that return a string containing the integer:
Code:
In [5]: int.__repr__(42)
Out[5]: '42'
 

Koren

Member
Ok, so after trying your re-re-edit, ive got it to finally recognize the list and print out the pokemon and abilites that the user enters, but its also printing out that hexadecimal thing as well.
Not sure I understand well, but if you have troubles, just ask.

Thank you for the quick response. This helped alot.
You're welcome... just happy to help.

I need to find a good tutorial to teach me because I really just dont gel well with the way our professor teaches this stuff.
Different persons need different approaches... As a Python teacher, I see each day that nothing works for everyone, and you need to be clever and offer different approaches. Hard to write something on paper, though.

About tutorial, the official Python tutorial is said to be good...

I must say I've yet to look at it, I've learned it using "Dive into Python" (which I really like, when many, many people hate it... but it's definitively a book for programmers, not for newcomers) then by reading the whole reference. So I don't have many good advices for this.

edit: Also, whats even dumber is that this is a pre-requisite class that teaches python, then in the next class, they switch to C++. Like who the fuck thought that up? Get all these beginners started on python and then switch over into a completely different language with 0 exposure to it. Brilliant stuff.
Depends what is the objective, and what time you have.

When you're preparing software engineers, I'd say switching language regularly and quickly *can* be good.

I'm still not convinced that Python is the best beginner language, though, if you're serious in CS (it's quite rewarding early, though). I'd probably choose ADA, myself.

That being said, half of the time, people choosing the languages in those situation do it for awful reasons (they know it, they like it, it's popular...)


Also, if you're beginners, I'm not sure I would introduce classes in Python as an entry for C++ (actually, I'm sure I wouldn't).

And I'd really like to know, if you've never done C++/Java, where you got the idea of creating Get_Name() and Get_Attribute() methods...?
 

Gurrry

Member
Check the edits, if you haven't because I've added more "straightforward" solutions.

The one before the last may be what you're after.


The list contains "Pokemon" objects. When you try to print the list, or when you try to print an element, like pokemon_list[0], Python try to display/print the object...

Unfortunately, he doesn't have a clue on how you would like this to appear, so the only thing it displays is the type (__main__.Pokemon object, an "object from the Pokemon class defined in the __main__ namespace) and the address in the memory.

Python can display all usual objects because they have a __str__ or a __repr__ method (or something equivalent)

For example, integers class int have (kinda) a __repr__ that return a string containing the integer:
Code:
In [5]: int.__repr__(42)
Out[5]: '42'

This makes sense. Thank you so much. I guess my only problem is I really dont have a great grasp on this whole __str__ or ___init____ stuff yet. This has been my first exposure to classes and O.O so its really a bigger hurdle for me than I thought it would be.

My main programming background comes from javascript/C# coding in unity. And even then, most of the stuff I did was kinda hacky anyway. So the more intermediate stuff like this is kinda overwhelming, but I think once I practice more with it, ill get it.

Thank you again for all the tips! :) you guys are life savers!

Also big shoutout to the user already in use. He PM'ed me with some tips as well, and hes a great person to this community. You and him are my life savers right now. :)

Not sure I understand well, but if you have troubles, just ask.


You're welcome... just happy to help.


Different persons need different approaches... As a Python teacher, I see each day that nothing works for everyone, and you need to be clever and offer different approaches. Hard to write something on paper, though.

About tutorial, the official Python tutorial is said to be good...

I must say I've yet to look at it, I've learned it using "Dive into Python" (which I really like, when many, many people hate it... but it's definitively a book for programmers, not for newcomers) then by reading the whole reference. So I don't have many good advices for this.


Depends what is the objective, and what time you have.

When you're preparing software engineers, I'd say switching language regularly and quickly *can* be good.

I'm still not convinced that Python is the best beginner language, though, if you're serious in CS (it's quite rewarding early, though). I'd probably choose ADA, myself.

That being said, half of the time, people choosing the languages in those situation do it for awful reasons (they know it, they like it, it's popular...)


Also, if you're beginners, I'm not sure I would introduce classes in Python as an entry for C++ (actually, I'm sure I wouldn't).

And I'd really like to know, if you've never done C++/Java, where you got the idea of creating Get_Name() and Get_Attribute() methods...?


yeah I have no issues changing languages, i actually want to learn C++, not python. i just find it bizzarre that the university thinks its a good idea to have a intro computer science class teach 1 language, then in the next class switch to something completely different. that seems counter intuitive. wouldnt it be better to just start at C++ and then get progressively more in depth with it as you progress through the courses?

I guess the idea is to teach people the fundamentals, then once they understand that using python, take those same ideas and apply them to C++... but it just seems like a bad way to do it.

And the way I got the get_name and get_attribute stuff was from his examples. If you want, you can even look at his website:

http://www.austincode.com/cosc1336/classes-and-objects.php

This is the main way he teaches us. He reads his website and doesnt do any live coding. I really would prefer him to code stuff in front of us so we can see why things work/dont work. Instead, I have to basically reverse engineer everything and figure it out from there.

I dont want someone to read this and think im just talking shit about the professor, i have learned alot so far in this class from him.

Its just that I think students, especially me, would learn even more if it were taught a different way. Im taking his next class for the C++ stuff, which im not sure if im excited for or dreading, but with something as complicated as computer science it isnt easy to teach a group of people that all have different learning methods. So I understand why he teaches it this way, but at the same time, I think it would be more beneficial if we saw him code things from scratch as examples that applied to the projects we have to do every week.
 

Koren

Member
This makes sense. Thank you so much. I guess my only problem is I really dont have a great grasp on this whole __str__ or ___init____ stuff yet. This has been my first exposure to classes and O.O so its really a bigger hurdle for me than I thought it would be.
It's not that difficult...

Briefly, there's no real difference between a "class" and a "type". You're trying to define a brand new "type" here, called Pokemon.

When you have an object, you have data (the value itself for an int, the name and ability for your Pokemon class) but also "methods" that come with it, which are just normal functions associated with the object.


The point is the key...

When you see a point in a function call, like in
Code:
foo.bar()
Python check the type of foo (that I'll write type_of_foo), and call
Code:
type_of_foo.bar(foo)
so, the bar function defined in class type_of_foo

I know, that seems complicated. But it's not.

When you write
Code:
pokemon_list.append(new_pokemon)
you know that it adds new_pokemon at the end of the list pokemon_list.

If fact, for Python, it means (since pokemon_list's type is "list")
Code:
list.append(pokemon_list, new_pokemon)

it works because the type "list" has a method "append".

You'll notice pokemon_list is "added" as the first argument automatically. That's the reason why you need "self" as the first argument of each methods in a class, it'll receive the object so that you can access its data. The name doesn't matter (you can call it the way you want), but "self" is the normal name.

The same way, when you write
Code:
pokemon_list[i].Get_Name()
it translate automatically into
Code:
Pokemon.Get_Name(pokemon_list[i])

Now for the interesting part. In Python, EVERYTHING work with class methods. And I mean it. There's plently of "special" method names that are used automatically by Python.

For example, when you write
Code:
len(L)
if L is a list, it translates it into
Code:
list.__len__(L)

If you want your object to have a len, you just have to create a method __len__(self) that return an integer which is the object length. Then, you can use len() with your object!

Try
Code:
    def __len__(self) :
        return 42
in your Pokemon class, and try len(pokemon_list[0]) ;)

So, now for the interesting part for your example.

When you create an object, Python call the special method __init__(self, ...) The arguments (beside the object itself, always first) are the ones you put in your object creation. So
Code:
new_pokemon = Pokemon(pokemon_name, pokemon_ability)
it creates an object of type Pokemon, then call
Code:
Pokemon.__init__(the_brand_new_object, pokemon_name, pokemon_ability)
and finally store the new object under the name new_pokemon.

(There's also a __new__(self), and a __del__(self) when it's destroyed, but let's keep those away for now).

You've seen __len__(self). There's plently others.

In fact, when you see
Code:
x + y
if x is an integer, it's translated into
Code:
int.__add__(x, y)

This way, you can create types that work with "+". Or anything else. All properties of Python objects come from the existence or the lack of those special methods between __ and __.

When you call print() on an object, Python want a string, because it can only print strings. So if the object is not a string, it calls __str__ to convert it into a string (if there's no __str__ in the class, it does what it can... he tries __repr__, and if it doesn't exist either, it prints what it can).

If Python needs to display it on screen (not with a print, but for example in the interactive prompt), it calls __repr__ to transform the object into a string.


Once you master this, it's really, really nice. And easy.

But with great powers come great responsabilities, so you shouldn't use __add__ and others methods without caution. ;) We've already discussed here what kind of awful things can happen with awful overloading in C++, that's the same here!
 

Gurrry

Member
It's not that difficult...

Briefly, there's no real difference between a "class" and a "type". You're trying to define a brand new "type" here, called Pokemon.

When you have an object, you have data (the value itself for an int, the name and ability for your Pokemon class) but also "methods" that come with it, which are just normal functions associated with the object.


The point is the key...

When you see a point in a function call, like in
Code:
foo.bar()
Python check the type of foo (that I'll write type_of_foo), and call
Code:
type_of_foo.bar(foo)
so, the bar function defined in class type_of_foo

I know, that seems complicated. But it's not.

When you write
Code:
pokemon_list.append(new_pokemon)
[code]
you know that it adds new_pokemon at the end of the list pokemon_list.

If fact, for Python, it means (since pokemon_list's type is "list")
[code]
list.append(pokemon_list, new_pokemon)
[code]

it works because the type "list" has a method "append".

You'll notice pokemon_list is "added" as the first argument automatically. That's the reason why you need "self" as the first argument of each methods in a class, it'll receive the object so that you can access its data. The name doesn't matter (you can call it the way you want), but "self" is the normal name.

The same way, when you write
[code]
pokemon_list[i].Get_Name()
[code]
it translate automatically into
[code]
Pokemon.Get_Name(pokemon_list[i])
[code]

Now for the interesting part. In Python, EVERYTHING work with class methods. And I mean it. There's plently of "special" method names that are used automatically by Python.
	
For example, when you write
[code]
len(L)
[code]
if L is a list, it translates it into
[code]
list.__len__(L)

If you want your object to have a len, you just have to create a method __len__(self) that return an integer which is the object length. Then, you can use len() with your object!

Try
Code:
    def __len__(self) :
        return 42
in your Pokemon class, and try len(pokemon_list[0]) ;)

So, now for the interesting part for your example.

When you create an object, Python call the special method __init__(self, ...) The arguments (beside the object itself, always first) are the ones you put in your object creation. So
Code:
new_pokemon = Pokemon(pokemon_name, pokemon_ability)
[code]
it creates an object of type Pokemon, then call
[code]
Pokemon.__init__(the_brand_new_object, pokemon_name, pokemon_ability)
[code]
and finally store the new object under the name new_pokemon.

(There's also a __new__(self), and a __del__(self) when it's destroyed, but let's keep those away for now).

You've seen __len__(self). There's plently others.

In fact, when you see
[code]
x + y
[code]
if x is an integer, it's translated into
[code]
int.__add__(x, y)
[code]

This way, you can create types that work with "+". Or anything else. All properties of Python objects come from the existence or the lack of those special methods between __ and __.

When you call print() on an object, Python want a string, because it can only print strings. So if the object is not a string, it calls __str__ to convert it into a string (if there's no __str__ in the class, it does what it can... he tries __repr__, and if it doesn't exist either, it prints what it can).

If Python needs to display it on screen (not with a print, but for example in the interactive prompt), it calls __repr__ to transform the object into a string.


Once you master this, it's really, really nice. And easy.

But with great powers come great responsabilities, so you shouldn't use __add__ and others methods without caution. ;) We've already discussed here what kind of awful things can happen with awful overloading in C++, that's the same here![/QUOTE]

Damn this is so useful dude.  Thank you so much.  This makes alot more sense to me than the stuff written on his website.  I appreciate you giving direct examples of each thing too.  That helps sooooooooooo freaking much.
 

Koren

Member
yeah I have no issues changing languages, i actually want to learn C++, not python. i just find it bizzarre that the university thinks its a good idea to have a intro computer science class teach 1 language, then in the next class switch to something completely different.
Doesn't seems that strange to me, if it's a CS class, but it can be done well, and awfully.

wouldnt it be better to just start at C++ and then get progressively more in depth with it as you progress through the courses?
Not sure, but that's a LONG discussion, and you need to hear the reasons (if they have) of the people who "designed" the class.

I guess the idea is to teach people the fundamentals, then once they understand that using python, take those same ideas and apply them to C++...
If that's it, that's not a good idea. The benefits of learning different languages is to see the similarities, but also the differences. You can easily "overlearn" something, and it's difficult to get rid of this later.

In the CS high school I worked some years ago, the students were learning, over a couple years, Caml, ADA, C/C++, Java, i86 assembly and probably more (plus tools like lex/yacc, etc.)

And the way I got the get_name and get_attribute stuff was from his examples. If you want, you can even look at his website:
Seems to me it's a Java or C++ guy that try to do Java/C++ in Python.

Not the greatest idea. Like Guido himself said, " "You can write FORTRAN in all languages", and "Java/C++" in Python ".

There's no reason to write those set/get functions in Python. attributes aren't protected like in Java / C++, you can even create and destroy them. The only reason would be the possibility of changing the "internal" representation, but that's not how it usually works in Python. And it adds bloat, that Python doesn't need, since it's already slow.

tl/dr.: that's unpythonic (not python "way of code"). Not uncommon, though, because many programmers have habits from other languages. I've seen it in a national exam here recently (and some people were quite harsh about the exam writer because of this)

This is the main way he teaches us. He reads his website and doesnt do any live coding. I really would prefer him to code stuff in front of us so we can see why things work/dont work.
Thanks.

Thanks, because I waste a lot of time programming in front of students (and answering all their wacky questions), and it's not always obvious it's the right thing to do. I believe it's right, though (that what I would have liked to see myself, now we HAVE videoprojectors...) but that's good to hear other people asking for it.

Especially in Python where the interactive interface works well (one of the main advantages for beginners, I think)

I dont want someone to read this and think im just talking shit about the professor, i have learned alot so far in this class from him.
I will *never* criticize someone else way of teaching (unless they're teaching wrong things, obviously), because there's as many ways as teachers and students. I don't think you're implying anything either. Like I said, his way work well for some students in your class, a bit worse for others.


Im taking his next class for the C++ stuff
Ah, if he does both classes, I understand better the setter/getter :)
 

gogojira

Member
I hope this isn't super rude/annoying to hop in and ask for a hot tip, but I've got a question:

Current career path suggests learning some level of code and at this juncture, Python fits the bill (vuln scanning, light pen testing, etc). I'm capping off a degree (non comp sci) this fall and will be heading into a proper comp science degree at the start of the year. My job pays for the schooling which is nice.

Regardless, I already started working my way through a pretty well-received book Python Crash Course. When I start college courses in January, they teach Javascript out the gate which is object oriented. Is my mind going to be fucked or is it OK to be taking in two different forms of programming at once?

Thanks for any help.
 

Koren

Member
Is my mind going to be fucked or is it OK to be taking in two different forms of programming at once?
I'd say it's OK if you're interested by Python and don't feel like it's annoying to learn it.

You'll have to keep your mind open, things are done differently in both languages, but seeing two different approaches, at the end of the day, should help you more than hinder you, I think.

Granted, you'll probably mix them a bit from time to time* (and end with a favorite) but nothing that will really "fuck your mind", and you'll probably be stronger at the end of the day. In both.

Just be really careful at the way it works, and don't think what's true in one language is also true in the other.


* As I said, I'm working with students, and currently many of them learn, at the same time, Python and Caml (vastly different approaches there). It's always funny to see them writing, in Python
Code:
def Fact(n) :
    def FactAux(n, acc) :
        if n == 1 :
            return acc
        return FactAux(n-1, acc*n)
    
    return FactAux(n, 1)
and be surprised when I tell them I see they've worked a lot in their Caml class ^_^

(for people who're not familiar with both languages, that's a perfect example of "writing ML in Python"... correct, although complicated for reasons that don't apply in Python, and the program will fail quickly because recursion doesn't work in Python like in Caml...)
 
Ok there HAS to be some way to do this.

We are working with SQL. And PHP. I need to have a table that has people in it.

Then give a form to the user that has a filter button that allows the user to filter based on what they enter.

So I have

Code:
($stmt = $mysqli->prepare("SELECT people.fname, people.lname, people.age FROM people WHERE people.fname = ? AND people.lname - ? AND people.age = ?")
Code:
$stmt->bind_param('ssi' ,$_POST['firstname'], $_POST['lastname'], $_POST['age']);

Now lets say my user only wants to sort by first name. They want anyone in my table with the first name John. So they submit the form which sends "John", NULL, NULL.

Which means then that my search will be WHERE fname = "John" AND lname = NULL AND age = NULL. Which wont work as far as I know. I dont think you can do WHERE "parameter = NULL" in mySQL. And even if you can, I don't want to search for rows where those values are NULL, I just want all Johns.

So how do I accomplish this? I was thinking of basically adding some if statement where "if parameter = NULL, set parameter to * (wildcard)". But that doesn't work unless I'm missing something.

So how would I actually accomplish what I want to do?
 

JesseZao

Member
Ok there HAS to be some way to do this.

We are working with SQL. And PHP. I need to have a table that has people in it.

Then give a form to the user that has a filter button that allows the user to filter based on what they enter.

So I have

Code:
($stmt = $mysqli->prepare("SELECT people.fname, people.lname, people.age FROM people WHERE people.fname = ? AND people.lname - ? AND people.age = ?")
Code:
$stmt->bind_param('ssi' ,$_POST['firstname'], $_POST['lastname'], $_POST['age']);

Now lets say my user only wants to sort by first name. They want anyone in my table with the first name John. So they submit the form which sends "John", NULL, NULL.

Which means then that my search will be WHERE fname = "John" AND lname = NULL AND age = NULL. Which wont work as far as I know. I dont think you can do WHERE "parameter = NULL" in mySQL. And even if you can, I don't want to search for rows where those values are NULL, I just want all Johns.

So how do I accomplish this? I was thinking of basically adding some if statement where "if parameter = NULL, set parameter to * (wildcard)". But that doesn't work unless I'm missing something.

So how would I actually accomplish what I want to do?

Only concat to the where clause if a filter is set.
 
Been awhile since I used php/mysql, but if you want a hard bind static statement, you could use LIKE instead of = and then you could use a wild card for no filter.

I did look into using LIKE instead of = in the initial prepare statement, but that runs into the problem of not finding exact things when the user does enter specific values, doesn't it?

edit: NOPE! That works. Thanks a bunch Jesse.

So I can probably add if (param === NULL) make param = "%".

Actually how do I check the parameters after the bind statement? $_POST['nameofvariable']?
 

Zoe

Member
Ok there HAS to be some way to do this.

We are working with SQL. And PHP. I need to have a table that has people in it.

Then give a form to the user that has a filter button that allows the user to filter based on what they enter.

So I have

Code:
($stmt = $mysqli->prepare("SELECT people.fname, people.lname, people.age FROM people WHERE people.fname = ? AND people.lname - ? AND people.age = ?")
Code:
$stmt->bind_param('ssi' ,$_POST['firstname'], $_POST['lastname'], $_POST['age']);

Now lets say my user only wants to sort by first name. They want anyone in my table with the first name John. So they submit the form which sends "John", NULL, NULL.

Which means then that my search will be WHERE fname = "John" AND lname = NULL AND age = NULL. Which wont work as far as I know. I dont think you can do WHERE "parameter = NULL" in mySQL. And even if you can, I don't want to search for rows where those values are NULL, I just want all Johns.

So how do I accomplish this? I was thinking of basically adding some if statement where "if parameter = NULL, set parameter to * (wildcard)". But that doesn't work unless I'm missing something.

So how would I actually accomplish what I want to do?

I usually do (lname = @parameter or @parameter is null) in the SQL for each one.

I rarely put SQL directly in my code though which is why I prefer to handle it that way.
 
I usually do (lname = @parameter or @parameter is null) in the SQL for each one.

I rarely put SQL directly in my code though which is why I prefer to handle it that way.

Not really sure what you mean here. Are you saying you don't use the prepare/bind_param statements?
 

Ambitious

Member
One week until my first day at my new job. I'm gonna have a coach to guide and support me in the first few days. That's cool.

They sent me their Handbook for New Employees. It sounds pretty amazing. Flat hierarchy, free choice of projects, free choice of work times (with a few limitations, of course) and so on. In fact, it reminded me of the working conditions at Valve. It's been a few years since I had a look at Valve's Handbook for New Employees, so I just skimmed it again in order to refresh my memory.

Actually.. the handbooks are not just similar. They have actually copied several pages directly from Valve's book and simply replaced the company name. Funny.
 

Airan

Member
Diving head first into C++ with Cocos2D-x, boy what a fucking nightmare this is, coming from C#. Adding a new class seems a chore.

Do I really have to include header files/forward declarations for each class that is referenced by a class? Why is there no default namespace created?

Why does cocos2d::Vector<T> not accept my custom type on build, but happily compiles <cocos2d::Object *> AND accepts my custom type at runtime??? (that appears to be a framework issue more than a C++ quirk from what I've researched, but it's aggravating nontheless).

Why is the pointer symbol a space apart within the Type identifier (e.g.: <cocos2d::Object __*__>) but not when defining method parameters?

Did C# handle all this pointer/reference stuff (like... which do I use when defining method parameters...?) behind my back? Man, I feel so spoiled with C#'s relative simplicity. This is humbling stuff.
 
Diving head first into C++ with Cocos2D-x, boy what a fucking nightmare this is, coming from C#. Adding a new class seems a chore.

Do I really have to include header files/forward declarations for each class that is referenced by a class?

Yes. C++ doesn't have modules the same way that other languages do. Remember, C# has assemblies which store all this metadata, so it's possible for one class to know about all the other stuff in the same assembly automatically. But for things not in the same assembly, you have to import them in C#, just like you have to include / forward declare them in C++. The ultimate result is the same: The language has to know what something is before you can reference it. C# just happens to be better at figuring this out because it has the assembly to fallback on.

Note that C++ is getting modules, but not for at least a couple more years.

Why is there no default namespace created?
There is. It's the global namespace. You can explicitly reference it by prepending a type name by ::, but if you don't give a namespace to a class, it's in the default (global) namespace.

Why does cocos2d::Vector<T> not accept my custom type on build, but happily compiles <cocos2d::Object *> AND accepts my custom type at runtime??? (that appears to be a framework issue more than a C++ quirk from what I've researched, but it's aggravating nontheless).
You'll have to elaborate on this. If it doesn't accept your custom type on build, how could it possibly accept it on runtime? If you can't compile your program, how can you run it?

Why is the pointer symbol a space apart within the Type identifier (e.g.: <cocos2d::Object __*__>) but not when defining method parameters?
The location of the pointer symbol is irrelevant, and probably just a style issue. Some people write cocos2d::Object* foo, some people write cocos2d::Object *foo, but you can even write cocos2d::Object*foo if you really want to piss off people reading your code.
 

Airan

Member
Yes. C++ doesn't have modules the same way that other languages do. Remember, C# has assemblies which store all this metadata, so it's possible for one class to know about all the other stuff in the same assembly automatically. But for things not in the same assembly, you have to import them in C#, just like you have to include / forward declare them in C++. The ultimate result is the same: The language has to know what something is before you can reference it. C# just happens to be better at figuring this out because it has the assembly to fallback on.

Note that C++ is getting modules, but not for at least a couple more years.


There is. It's the global namespace. You can explicitly reference it by prepending a type name by ::, but if you don't give a namespace to a class, it's in the default (global) namespace.


You'll have to elaborate on this. If it doesn't accept your custom type on build, how could it possibly accept it on runtime? If you can't compile your program, how can you run it?


The location of the pointer symbol is irrelevant, and probably just a style issue. Some people write cocos2d::Object* foo, some people write cocos2d::Object *foo, but you can even write cocos2d::Object*foo if you really want to piss off people reading your code.

I admit I know very little of the internals of CLI, so exploring C++ only to find I was taking for granted many of the conveniences C# provided was definitely enlightening, and made me appreciate the language much more.

I thought adding a class without a defined namespace would place it into some sort of default global namespace (and thus can be referenced by other classes without a defined namespace) but this doesn't seem to be true in my very limited experience. I'll definitely have to tinker around some more.

You'll have to elaborate on this. If it doesn't accept your custom type on build, how could it possibly accept it on runtime? If you can't compile your program, how can you run it?

Cocos2d-x has a class Vector which if I understood correctly is similar to a List<T> in C#.

I want to store a collection of objects of my custom class. Let's call this class "ButtonSprite". This custom class inherits one of Cocos2ds base classes, cocos2d::Sprite.

So in my HelloWorld.cpp I write out:
Code:
this->buttonArray = cocos2d::Vector<ButtonSprite*>{ 1 };

Which should initialize a collection of type ButtonSprite, of size 1. For some reason, when compiling it doesn't seem to accept it (it throws this error "Invalid Type for cocos2d::Vector!"), but if I change the Vector type to be cocos2d::Object, the root class of all of cocos2d's classes, then it'll compile and accept my custom class.

What confuses me most is that in HelloWorld.h if I add #include "ButtonSprite.h" then it compiles fine. But apparently including header references in header files is a big no no for compile time reasons so I try to do forward declarations:

Code:
//#include "ButtonSprite.h" //compiles
class ButtonSprite; //nope

class HelloWorld : public cocos2d::Layer
{	

public:
	cocos2d::Vector<cocos2d::ButtonSprite*> buttonArray;
//rest of header

which leads to the compile issue above.
 
If I have a form on my html website, lets say with 3 fields:

Name:
Age:
Gender:

Upon clicking submit, the user provided values in the form are sent to some site via a POST request.

Lets say the user submits:

Laura
37

Now nothing was entered for gender. Does the POST request treat this as an empty string "" or as NULL?
 
I admit I know very little of the internals of CLI, so exploring C++ only to find I was taking for granted many of the conveniences C# provided was definitely enlightening, and made me appreciate the language much more.

I thought adding a class without a defined namespace would place it into some sort of default global namespace (and thus can be referenced by other classes without a defined namespace) but this doesn't seem to be true in my very limited experience. I'll definitely have to tinker around some more.



Cocos2d-x has a class Vector which if I understood correctly is similar to a List<T> in C#.

I want to store a collection of objects of my custom class. Let's call this class "ButtonSprite". This custom class inherits one of Cocos2ds base classes, cocos2d::Sprite.

So in my HelloWorld.cpp I write out:
Code:
this->buttonArray = cocos2d::Vector<ButtonSprite*>{ 1 };

Which should initialize a collection of type ButtonSprite, of size 1. For some reason, when compiling it doesn't seem to accept it (it throws this error "Invalid Type for cocos2d::Vector!"), but if I change the Vector type to be cocos2d::Object, the root class of all of cocos2d's classes, then it'll compile and accept my custom class.

What confuses me most is that in HelloWorld.h if I add #include "ButtonSprite.h" then it compiles fine. But apparently including header references in header files is a big no no for compile time reasons so I try to do forward declarations:

Code:
//#include "ButtonSprite.h" //compiles
class ButtonSprite; //nope

class HelloWorld : public cocos2d::Layer
{	

public:
	cocos2d::Vector<cocos2d::ButtonSprite*> buttonArray;
//rest of header

which leads to the compile issue above.

Can you paste the exact compiler error message you get? It doesn't surprise me you don't get an error in one case but do in another.

C++ checks templates for syntax errors as soon as it sees them, but it doesn't check what happens when it actually does the type substitution until you actually use the template with a particular type. If you never use it, it will never check if it's a valid substitution
 

Somnid

Member
If I have a form on my html website, lets say with 3 fields:

Name:
Age:
Gender:

Upon clicking submit, the user provided values in the form are sent to some site via a POST request.

Lets say the user submits:

Laura
37

Now nothing was entered for gender. Does the POST request treat this as an empty string "" or as NULL?

It might make a little more sense to understand how forms are represented in HTTP (which is how it's transferred over the wire). Your server framework will then figure out what to do with it. The literal request payload will be:

Name=Laura&Age=37&Gender=

That last bit may be interpreted as "" or null. It's up to whatever server code you're running and should hopefully be documented.
 

Airan

Member
Can you paste the exact compiler error message you get? It doesn't surprise me you don't get an error in one case but do in another.

C++ checks templates for syntax errors as soon as it sees them, but it doesn't check what happens when it actually does the type substitution until you actually use the template with a particular type. If you never use it, it will never check if it's a valid substitution

Visual Studio output:

Code:
AppDelegate.cpp
HelloWorldScene.cpp
...\cocos2d\cocos\base\ccvector.h(113): error C2338: Invalid Type for cocos2d::Vector<T>! (compiling source file ..\Classes\AppDelegate.cpp)
...\cocos2d\cocos\base\ccvector.h(110): note: while compiling class template member function 'cocos2d::Vector<ButtonSprite *>::Vector(void)' (compiling source file ..\Classes\AppDelegate.cpp)
...\classes\helloworldscene.h(39): note: see reference to function template instantiation 'cocos2d::Vector<ButtonSprite *>::Vector(void)' being compiled (compiling source file ..\Classes\AppDelegate.cpp)
...\classes\helloworldscene.h(22): note: see reference to class template instantiation 'cocos2d::Vector<ButtonSprite *>' being compiled (compiling source file ..\Classes\AppDelegate.cpp)

Drilling into the error itself leads me to CCVector.h:

Code:
  /** Constructor. */
    Vector<T>()
    : _data()
    {
        static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!");
    }

It seems to attempt to confirm whether my Custom type is convertible... convertible to a reference type???
 
Visual Studio output:

Code:
AppDelegate.cpp
HelloWorldScene.cpp
...cocos2dcocosbaseccvector.h(113): error C2338: Invalid Type for cocos2d::Vector<T>! (compiling source file ..ClassesAppDelegate.cpp)
...cocos2dcocosbaseccvector.h(110): note: while compiling class template member function 'cocos2d::Vector<ButtonSprite *>::Vector(void)' (compiling source file ..ClassesAppDelegate.cpp)
...classeshelloworldscene.h(39): note: see reference to function template instantiation 'cocos2d::Vector<ButtonSprite *>::Vector(void)' being compiled (compiling source file ..ClassesAppDelegate.cpp)
...classeshelloworldscene.h(22): note: see reference to class template instantiation 'cocos2d::Vector<ButtonSprite *>' being compiled (compiling source file ..ClassesAppDelegate.cpp)

Drilling into the error itself leads me to CCVector.h:

Code:
  /** Constructor. */
    Vector<T>()
    : _data()
    {
        static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!");
    }

It seems to attempt to confirm whether my Custom type is convertible... convertible to a reference type???

Search CCVector.h for the line "typedef XXX Ref;" What is Ref? You might have to follow this multiple steps until you get to some function of T.
 

Airan

Member
Search CCVector.h for the line "typedef XXX Ref;" What is Ref? You might have to follow this multiple steps until you get to some function of T.

Ref is a class in Cocos2Dx. I'm not sure what to make out of this, considering it works with the include I mentioned in a previous post.

Correct me if I'm wrong, but my custom class ButtonSprite inherits Sprite, which is a subclass of Node, which itself is a subclass of Ref. So it should assert correctly. The only thing throwing me off is the pointer to Ref. Head-scratching!
 
Ref is a class in Cocos2Dx. I'm not sure what to make out of this, considering it works with the include I mentioned in a previous post.

Correct me if I'm wrong, but my custom class ButtonSprite inherits Sprite, which is a subclass of Node, which itself is a subclass of Ref. So it should assert correctly. The only thing throwing me off is the pointer to Ref. Head-scratching!

I have a suspicion of what your problem is, but rather than just tell you, let's see if you can make the compiler tell you what the problem is.

Try writing the following code inside of some function:

Code:
ButtonSprite *b = nullptr;
Ref *r = static_cast<Ref *>(b);

And see if you get a compiler error.
 
Gah...........

Code:
if($_POST['pid'] == '')
{$filter[] = " (id LIKE '%' or id is NULL) ";}
else
{
 $filter[] = " id = " . $_POST['pid']; 
}
if($_POST['fname'] == '')
{$filter[] = " (fname LIKE '%' or fname is NULL) ";}
else
{
 $filter[] = " fname = " . $_POST['fname']; 
}
$query = "SELECT * FROM people";

$query .= " WHERE " . implode(" AND ", $filter);

(!($stmt = $mysqli->prepare($query))){
	echo "Prepare failed: "  . $stmt->errno . " " . $stmt->error;
}

This code is not working and I think I know why. I get the error "Trying to get property of non-object".

I believe this is because the query becomes (lets say the user entered James as the first name)

SELECT * FROM patients WHERE (id LIKE '%' or id is NULL) AND fname = James.

Which isn't valid SQL. Because James needs to be in quotes.

But how do I get the variable in quotes within my giant query string?
 

Airan

Member
I have a suspicion of what your problem is, but rather than just tell you, let's see if you can make the compiler tell you what the problem is.

Try writing the following code inside of some function:

Code:
ButtonSprite *b = nullptr;
Ref *r = static_cast<Ref *>(b);

And see if you get a compiler error.

Compiles fine with either #include and forward declaration of ButtonSprite in helloworld.h. I'm reading that is_convertible checks whether implicit conversion is possible, while static_cast is an explicit conversion, so... I guess I have to fix it to make implicit conversion possible?
 

Chris R

Member
Gah...........

But how do I get the variable in quotes within my giant query string?

I have ZERO php knowledge, but would

$filter[] = " fname = '" . $_POST['fname'] . "'"; work?

Of course, this is bad bad bad bad bad because I'm pretty sure you could get SQL Injected with this, but again, like I said, zero php knowhow.
 
Compiles fine with either #include and forward declaration of ButtonSprite in helloworld.h. I'm reading that is_convertible checks whether implicit conversion is possible, while static_cast is an explicit conversion, so... I guess I have to fix it to make implicit conversion possible?

If that works try

Code:
ButtonSprite *b = nullptr;
Ref *r = b;

And see if you get a better error

At this point though I'm suspicious that that actually worked. I would try putting that code inside your main() function to be sure
 

ricki42

Member
Gah...........

This code is not working and I think I know why. I get the error "Trying to get property of non-object".

I believe this is because the query becomes (lets say the user entered James as the first name)

SELECT * FROM patients WHERE (id LIKE '%' or id is NULL) AND fname = James.

Which isn't valid SQL. Because James needs to be in quotes.

But how do I get the variable in quotes within my giant query string?

I don't know SQL, but does escaping the quotes work?
Code:
 $filter[] = " fname = \"" . $_POST['fname'] . "\"";

Also, I think instead of "== '' " you can use isset to check if the variable has been set.
 

Koren

Member
Also, I think instead of "== '' " you can use isset to check if the variable has been set.
If I'm not mistaken, an empty field in a form *is* set, so it wouldn't work (or I haven't understood your suggestion)

!empty() won't work well either (it would give True for "0" if I'm not mistaken).
 

ricki42

Member
If I'm not mistaken, an empty field in a form *is* set, so it wouldn't work (or I haven't understood your suggestion)

!empty() won't work well either (it would give True for "0" if I'm not mistaken).

Ah, didn't know that, thanks for correcting!
 
Compiles fine with either #include and forward declaration of ButtonSprite in helloworld.h. I'm reading that is_convertible checks whether implicit conversion is possible, while static_cast is an explicit conversion, so... I guess I have to fix it to make implicit conversion possible?

Wait. What header file is ButtonSprite.h defined in? And what file are you making a CCVector<ButtonSprite*> from? Is the first header included from the second file? This won't work with a forward declaration.
 

Airan

Member
Wait. What header file is ButtonSprite.h defined in? And what file are you making a CCVector<ButtonSprite*> from? Is the first header included from the second file? This won't work with a forward declaration.

Code:
ButtonSprite *b = nullptr;
Ref *r = b;

compiles and runs fine. I assuming this means implicit conversion is possible, so it has to be something to do with the Vector initialisation... right?

The default classes the cocos2d automatically creates are main.cpp, appdelegate.cpp, helloworld.cpp. I added buttonsprite.cpp.

It instantiates classes in the following order:
main > appdelegate > helloworld > buttonsprite

#include "ButtonSprite.h" and cocos2d::Vector<ButtonSprite*> are both declared in helloworld.h.

helloworld.h
Code:
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
//#include "ButtonSprite.h"

class ButtonSprite;

class HelloWorld : public cocos2d::Layer
{	

public:
      ...

      cocos2d::Vector<ButtonSprite*> buttonArray;

      ...
};

#endif // __HELLOWORLD_SCENE_H__

helloworld.cpp
Code:
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
	...
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	...

        this->buttonArray = cocos2d::Vector<ButtonSprite*>{ 1 };
        ...
}
 
Code:
ButtonSprite *b = nullptr;
Ref *r = b;

compiles and runs fine. I assuming this means implicit conversion is possible, so it has to be something to do with the Vector initialisation... right?

The default classes the cocos2d automatically creates are main.cpp, appdelegate.cpp, helloworld.cpp. I added buttonsprite.cpp.

It instantiates classes in the following order:
main > appdelegate > helloworld > buttonsprite

#include "ButtonSprite.h" and cocos2d::Vector<ButtonSprite*> are both declared in helloworld.h.

helloworld.h
Code:
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
//#include "ButtonSprite.h"

class ButtonSprite;

class HelloWorld : public cocos2d::Layer
{	

public:
      ...

      cocos2d::Vector<ButtonSprite*> buttonArray;

      ...
};

#endif // __HELLOWORLD_SCENE_H__

helloworld.cpp
Code:
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
	...
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	...

        this->buttonArray = cocos2d::Vector<ButtonSprite*>{ 1 };
        ...
}

The include of ButtonSprite.h is commented out, and instead you have only a forward declaration. Normally this would be fine, but since this particular vector class insists that it be convertible, the compiler has to know that it is convertible, and a forward declaration isn't enough information.

Uncomment the #include and remove the forward declaration
 

Airan

Member
The include of ButtonSprite.h is commented out, and instead you have only a forward declaration. Normally this would be fine, but since this particular vector class insists that it be convertible, the compiler has to know that it is convertible, and a forward declaration isn't enough information.

Uncomment the #include and remove the forward declaration

I see. So there really is no way around header file references in this particular situation. Thanks for all your help.
 
I can't figure this out... Javascript/Handlebars/Handlebars Express issues

Why wont my page update until I refresh?

3 relevant files here. Big post incoming.

First is a handlebars file.
Code:
<form id="workForm">
<fieldset>
<legend>Add Workout</legend>
<label for="name">Name </label>
<input type="text" name="name" id="name">
<label for="reps">Reps </label>
<input type="number" name="reps" id="reps">
<label for="weight">Weight </label>
<input type="number" name="weight" id="weight">
<label for="date">Date </label>
<input type="date" name="date" id="date"></input>
<label>lbs</label>
<input type="radio" name="pound" value="1" checked="checked">
<label>kgs</label>
<input type="radio" name="pound" value="0">
<input type="submit" id="addnew" value="submit">
</fieldset>
</form>
<h1>Recorded Workouts</h1>
<table id="rwout">
<tr>
<th id="hidden">ID</th>
<th>Name</th>
<th>Reps</th>
<th>Weight</th>
<th>LBS/KGS</th>
<th>Date</th>
</tr>
{{error}}
{{#each workout}}
<tr>
<td id="hidden">{{this.id}}</td>
<td>{{this.name}}</td>
<td>{{this.reps}}</td>
<td>{{this.weight}}</td>
<td>{{this.pound}}</td>
<td>{{this.date}}</td>
<td><input type="button" value="Edit"></td>
<td><input type="button" value="Delete"></td>
</tr>
{{/each}}
</table>

So basically I want the table data to be generated when I send it the proper context. The submit button does nothing. But I add functionality to it using javascript.

Code:
document.getElementById('addnew').addEventListener('click', function(event){
    
    var req = new XMLHttpRequest();
    var qStr = '/insert';
    
	var queryExt= "name="+workForm.elements.name.value+
				"&reps="+workForm.elements.reps.value+
				"&weight="+workForm.elements.weight.value+
				"&date="+workForm.elements.date.value+
				"&pound="+workForm.elements.pound.value;
    req.open("GET", qStr + "?" + queryExt,true);
    req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    req.addEventListener('load',function(){
	if(req.status >= 200 && req.status < 400){
	    var res = JSON.parse(req.responseText);
		console.log(res);

	} 
	else
	{
		console.log("Error in network request: " + request.statusText);
	}
    });
    req.send(qStr + "?" + queryExt);
	event.preventDefault();

});

So now when I click submit after filling the form with values. It sends the data to my /insert page. Which then processes the data. Meanwhile I use preventDefault() so that I don't actually navigate away from the base page. The data is sent to /insert, but the user stays on /

Here is what my pages do:
Code:
//selecting data
app.get('/', function(req, res, next){
	var context = {}
	pool.query("Select * from `workouts`", function(err, rows, fields){
		if(err){
			next(err);
			return;
		}
		
		var workoutData = [];
		for (var d in rows){
			workoutData.push({'id':rows[d].id, 'name': rows[d].name, 'reps':rows[d].reps, 'weight':rows[d].weight, 'date':rows[d].date, 'pound':rows[d].lbs})
		}
		
		context.workout = workoutData;
		res.render('home', context);
	});
});

//insert data
app.get('/insert',function(req,res,next){
  pool.query("INSERT INTO `workouts` (`name`, `reps`, `weight`, `date`, `lbs`) VALUES (?, ?, ?, ?, ?)", [req.query.name, req.query.reps, req.query.weight, req.query.date, req.query.pound], function(err, result){
    if(err){
      next(err);
      return;
    }
  });
});

Ok so the base page should be running this select query, and populating my table. And it does that. But when I insert a new row into the table, I have to manually refresh the / base page before it shows up. I want the table to update automatically without the user having to refresh. How do I accomplish that? Is there a way to force the page to run its selection query again without having to manually refresh?
 
Top Bottom