The "IT DOESN'T WORK!" thread

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
thoughtfully
Posts: 2243
Joined: Thu Nov 01, 2007 12:25 am UTC
Location: Minneapolis, MN
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby thoughtfully » Sun Aug 31, 2014 1:29 am UTC

Code: Select all

#undef __cplusplus


Alas, if only making C++ go away were so easy!
Image
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
-- Antoine de Saint-Exupery

User avatar
Diadem
Posts: 5585
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Mon Sep 01, 2014 11:08 am UTC

A C++ question.

I want to make a logging class, so I can type something like

Code: Select all

log << "Hello" << "World" << std::endl;

And have it do nothing in the release build, but output it to both screen and a file in the debug build. How do I do this? With a macro this is easy. But macros are awkward, and I would prefer to keep the exact same syntax as using cout would have. Since I'm conditionally compiling stuff, I am obviously going to have to do something with the preprocessor.

My first attempt was:

Code: Select all

class LogManager {
  template <class T>
  friend LogManager& operator<<(LogManager& out, const T& msg) {
    std::cout << msg;
    file << msg; // file defined somewhere else
    return out;
  }
};
#ifdef _DEBUG
LogManager log;
#else
#define log while(0) std::cout
#endif


But first of all this is a bit ugly. The second to last line makes me cringe. Is there a prettier way of doing this?

Worse though, it doesn't work.

Code: Select all

log << 3; // works
log << "Hello" << "World"; // works
log << std::endl; // compile error C2914 and C2676 ('template argument is ambiguous' and 'LogManager does not define this operator').


Because apparently std::endl isn't an object at all, but a function... Huh.

So, does anybody know how to solve these problems?
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
Jplus
Posts: 1686
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Jplus » Mon Sep 01, 2014 2:27 pm UTC

std::endl is a pointer to a function with a single argument, which happens to be the (old-fashioned) standard for I/O manipulators. The standard explicitly defines basic_ostream << basic_ostream& (*) (basic_ostream&). Since your LogManager isn't an instance of (a subclass of) basic_ostream, the expression log << endl is ambiguous. I think you could fix it by explicitly defining LogManager << basic_ostream& (*) (basic_ostream&). If that doesn't work, you can either opt to provide your own LogManager::endl or to make LogManager a subclass of basic_ostream (although the latter would probably be a pain).

As a more elegant solution to your "do nothing in release builds" requirement, you can define a LogAbsorber class which accepts the filestream syntax while doing nothing, and make log an instance of that for release builds. Or equivalently, and perhaps even more elegantly, just compile the function body of LogManager << T conditionally (except for the return out part of course).

If I'm right <cassert> uses the negative macro NDEBUG for release compilation, so that might be a more "standard" way of switching the log on or off.
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Mon Sep 01, 2014 8:06 pm UTC

The basic problem is that std::endl is overloaded, so passing it to a template argument that vague doesn't work. All overloads seem valid, and your call is ambiguous.

One approach that might work is:

Code: Select all

template<class T, class U>using second_type_t=U;

// ...

  template <class T>
  friend
  second_type_t<decltype(std::cout << msg), LogManager& >
  operator<<(LogManager& out, const T& msg) {

which tests if the T in question can be passed to std::cout using operator<< before accepting it.

The decltype(std::cout<<msg) gets discarded, but evaluated.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Diadem
Posts: 5585
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Tue Sep 02, 2014 7:59 am UTC

Thanks! This problem has turned out to be rather interesting, and consequently rather educating.

The problem is indeed that the double template situation (operator<< and std::endl) can't be resolved by the compiler. After some googling I discovered that there are in fact 3 cases I need to cover, to also get things like setprecision to work. So you end up with the operator<< just like above, but then 3 extra non-templated overloads specializations. "basic_ostream& (*) (basic_ostream&)", "ios_base& (*) (ios_base&)" and finally the rather involved "basic_ios<ostream::char_type, ostream::traits_type>& (*) (basic_ios<ostream::char_type, ostream::traits_type>&)". These can just call the template version with explicit template parameters. It seems to work in all cases now, but it ain't exactly pretty.

I then did the release build case pretty much exactly like suggested here, by implementing an empty manager class and instantiating from there for the release build. I am wondering though how much that will slow my code down. You're creating a class and recursively calling a function a number of times. The class is empty and the function does nothing, so theoretically at least it should be possible to optimize that all away, but I don't know if that really happens. Hmm.

I also looked into inheriting from basic_ostream, but this seems even more complicated.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby korona » Tue Sep 02, 2014 8:56 am UTC

I'd suggest using an existing logging library as there are many good ones (e.g. the ones from Boost or Google) and you're really reinventing the wheel here.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Tue Sep 02, 2014 3:02 pm UTC

Diadem, what is wrong with the decltype version? No C++11 support?
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
phlip
Restorer of Worlds
Posts: 7525
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Tue Sep 09, 2014 12:47 pm UTC

Does anyone know how to make MySQL play nice with astral-plane unicode characters? When I try it just cuts strings off at the first one and issues a warning...

Code: Select all

>>> conn = oursql.connect(host="localhost", user="test", passwd="passwordgoeshere", db="test", use_unicode=True, charset="utf8")
>>> cur = conn.cursor()
>>> cur.execute("CREATE TABLE TEST(TXT VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL)")
>>> cur.execute("INSERT INTO TEST(TXT) VALUES(?)", ("Test test",))
>>> cur.execute("INSERT INTO TEST(TXT) VALUES(?)", ("Test \uabcd test",))
>>> cur.execute("INSERT INTO TEST(TXT) VALUES(?)", ("Test \U000ABCDE test",))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "cursor.pyx", line 122, in oursql.Cursor.execute (oursqlx/oursql.c:17060)
  File "statement.pyx", line 405, in oursql._Statement.execute (oursqlx/oursql.c:11467)
  File "util.pyx", line 105, in oursql._do_warnings_query (oursqlx/oursql.c:4178)
oursql.CollatedWarningsError: (None, 'query caused warnings', [(<class 'oursql.Warning'>, ("Incorrect string value: '\\xF2\\xAB\\xB3\\x9E t...' for column 'TXT' at row 1", 1366))])
>>> cur.execute("SELECT TXT FROM TEST")
>>> print(list(cur))
[('Test test',), ('Test \uabcd test',), ('Test ',)]

If I remember rightly I've had some amount of luck before in other languages doing the stupid double-UTF thing, where you encode the string as UTF-16, then take each of those 16-bit words and apply the UTF-8 transform to that... but Python won't let me do that, since it's not real UTF-8, it's trying to save me from myself...

"Use not-MySQL" is not really a useful answer... if that was an option, I'd be all over it already.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Tue Sep 09, 2014 2:31 pm UTC

http://dev.mysql.com/doc/refman/5.6/en/ ... icode.html ?

They claim UTF-32 support. And utf8mb4 which claims to support everything utf-32 does.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
phlip
Restorer of Worlds
Posts: 7525
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Tue Sep 09, 2014 3:20 pm UTC

Yakk wrote:utf8mb4

... Goddamn it MySQL. You're terrible at this.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Tue Sep 09, 2014 3:45 pm UTC

utfmb3 aka not really utf-8 (mostly! guys, I'm mostly utf-8!), but it is an alias for utf8!
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
phlip
Restorer of Worlds
Posts: 7525
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Wed Sep 10, 2014 5:11 am UTC

OK, so for the benefit of anyone coming across this via Google, here's all the changes I had to make:

Code: Select all

>>> import oursql, codecs
>>> codecs.register(lambda name: codecs.lookup('utf8') if name == 'utf8mb4' else None)
>>> conn = oursql.connect(host="localhost", user="test", passwd="passwordgoeshere", db="test", use_unicode=True, charset="utf8mb4")
>>> cur = conn.cursor()
>>> cur.execute("CREATE TABLE TEST(TXT VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL)")
>>> cur.execute("INSERT INTO TEST(TXT) VALUES(?)", ("Test test",))
>>> cur.execute("INSERT INTO TEST(TXT) VALUES(?)", ("Test \uABCD test",))
>>> cur.execute("INSERT INTO TEST(TXT) VALUES(?)", ("Test \U000ABCDE test",))
>>> cur.execute("SELECT TXT FROM TEST")
>>> print(list(cur))
[('Test test',), ('Test \uabcd test',), ('Test \U000abcde test',)]

oursql uses the same parameter to determine both "What to we tell MySQL is the codec we're using to send text" and "What codec to we pass to str.encode when sending unicode data to MySQL"... the former needs to be "utf8mb4", so we need to make the latter recognise that same codec name, hence the codecs.register call. (Found via this.) After that, changing the codec name both in the connect() call and the table definition worked.

To upgrade existing tables:

Code: Select all

ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
ALTER TABLE TEST CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby korona » Wed Sep 10, 2014 10:13 am UTC

Wow, that is really horrible.

User avatar
NecklaceOfShadow
Posts: 775
Joined: Sun May 03, 2009 7:40 pm UTC
Location: In the alchemical aether
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby NecklaceOfShadow » Sun Oct 05, 2014 6:25 pm UTC

*sigh*

Just don't understand how python's import system works. Either py2 or py3. So let's say there's a directory structure

Code: Select all

basedir/
|__ dirA/
|____ file1.py
|__ dirB/
|____ file 2.py


Can't make it so that can import methods from file1 into file2. Everything gives System Error or Value Error. Have tried to read the documentation but it hasn't been illuminating.
Significantly less weird than I used to be. Still pretty weird.

οὗτός ἐστιν Ἀγαμέμνων, ἐμὸς
πόσις, νεκρὸς δὲ τῆσδε δεξιᾶς χερός
ἔργον δικαίας τέκτονος. τάδ’ ὧδ’ ἔχει.

User avatar
thoughtfully
Posts: 2243
Joined: Thu Nov 01, 2007 12:25 am UTC
Location: Minneapolis, MN
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby thoughtfully » Sun Oct 05, 2014 6:43 pm UTC

NecklaceOfShadow wrote:*sigh*

Just don't understand how python's import system works. Either py2 or py3. So let's say there's a directory structure

Code: Select all

basedir/
|__ dirA/
|____ file1.py
|__ dirB/
|____ file 2.py


Can't make it so that can import methods from file1 into file2. Everything gives System Error or Value Error. Have tried to read the documentation but it hasn't been illuminating.

Have you read up on packages?
Python 2.7
Python3.4

I'm familiar with Python 2.x. Python 3 may have added some wrinkles. In 2.x (for all "x" for which the packages system is suppported, which is all "x" you probably care about, but I'm not sure offhand if it's all x or not):
Your basedir will need to be the current directory or in sys.path. Either:

Rename dirA/file1.py to dirA/__init__.py, and

Code: Select all

import dirA

or create an empty dirA/__init__.py, and

Code: Select all

import dirA.file1


and analogously with dirB.

A common oops with import problems is having a match you aren't expecting when Python searches, usually in the current directory. You might also verify that Python isn't hittting one of these. One way to check is to look in sys.modules to see the path to the file that is loaded.
Image
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
-- Antoine de Saint-Exupery

User avatar
NecklaceOfShadow
Posts: 775
Joined: Sun May 03, 2009 7:40 pm UTC
Location: In the alchemical aether
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby NecklaceOfShadow » Mon Oct 06, 2014 5:52 pm UTC

Yes, I read up on packages. It was the first thing I did, so I could try to figure out how to organize the project. After reading both of those pages, and following what they said to the best I could, I got nowhere. Hence asking for help. Running from the basedir directory:

Code: Select all

$ tree
basedir
├── [4.0K]  dirA
│   ├── [  79]  file1.py
│   └── [   0]  __init__.py
└── [4.0K]  dirB
    └── [ 173]  file2.py

$ python2 dirB/file2.py
Traceback (most recent call last):
  File "dirB/file2.py", line 1, in <module>
    import dirA.file1
ImportError: No module named dirA.file1


Just tried to add the following code to the top of file2. It works, but it's ugly, and I hope there's a cleaner way to do it.

Code: Select all

import sys
sys.path.append('/home/<blah>/code/basedir')
Significantly less weird than I used to be. Still pretty weird.

οὗτός ἐστιν Ἀγαμέμνων, ἐμὸς
πόσις, νεκρὸς δὲ τῆσδε δεξιᾶς χερός
ἔργον δικαίας τέκτονος. τάδ’ ὧδ’ ἔχει.

User avatar
thoughtfully
Posts: 2243
Joined: Thu Nov 01, 2007 12:25 am UTC
Location: Minneapolis, MN
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby thoughtfully » Mon Oct 06, 2014 9:44 pm UTC

If you read the documentation carefully, it states that the directory of the input script (i.e."__main__" module) is what is included when searching for modules. This is the current directory if you are using the interactive interpreter (and haven't changed directories), or if you run a python script from the current directory.

Try to imagine doing it the other way. scripts in one directory that reference each other would have to go through hoops to do so, and unintentional loading of a module from the current directory could lead to stuff not working or security problems.

Code: Select all

0 % mkdir foo bar
0 % echo 'print "Foo package"' >foo/__init__.py
0 % echo 'print "Bar package"' >bar/__init__.py
0 % echo 'print "foo module"' > foo/foomod.py
0 % echo 'import bar' >> foo/foomod.py
0 % python foo/foomod.py
foo module
Traceback (most recent call last):
  File "foo/foomod.py", line 2, in <module>
    import bar
ImportError: No module named bar
1 % python
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from foo import foomod
Foo package
foo module
Bar package
>>>
0 % python
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo.foomod
Foo package
foo module
Bar package


Adding a relative path to sys.path is fine (it's only in effect while that instance of the interpreter is running), and you might be able to use

Code: Select all

os.path.dirname(sys.argv[0])

to good effect.

It isn't too tricky. Just get the rules straight and you should be fine.
Image
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
-- Antoine de Saint-Exupery

User avatar
hotaru
Posts: 1016
Joined: Fri Apr 13, 2007 6:54 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby hotaru » Sun Dec 07, 2014 2:29 am UTC

I'm trying to position symbols on an svg clock face, and I'm wondering if there's a way to get my initial approach of putting all the symbols in the same place and then using "transform" to rotate them around the center of the clock to work correctly. the solution I came up with was to just calculate the coordinates for each symbol, but if like to know, is there a way to make this work, or is positioning text in svg just horribly broken?
Last edited by hotaru on Sun Dec 07, 2014 8:30 am UTC, edited 1 time in total.

Code: Select all

factorial product enumFromTo 1
isPrime n 
factorial (1) `mod== 1

User avatar
phlip
Restorer of Worlds
Posts: 7525
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Sun Dec 07, 2014 3:14 am UTC

What are you seeing that's incorrect? It looks OK to me...

I mean, usually on a clock that's set out like that you'd have the 12 be the right way up and the 6 be upside down, but still... the actual positioning seems to be working for me (looking at it in Firefox and Chrome at least).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
hotaru
Posts: 1016
Joined: Fri Apr 13, 2007 6:54 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby hotaru » Sun Dec 07, 2014 4:01 am UTC

phlip wrote:What are you seeing that's incorrect? It looks OK to me...

I mean, usually on a clock that's set out like that you'd have the 12 be the right way up and the 6 be upside down, but still... the actual positioning seems to be working for me (looking at it in Firefox and Chrome at least).

here's what I'm seeing in chrome:
Image

for some reason firefox (actually aurora, which I have updated since then) was rendering it that way before, but now seems to be showing what I expected. I figured since firefox and chrome were rendering it the same way, that was just the way that document should be rendered.

rotating the symbols to put them right side up is trivial, now that they're positioned correctly in firefox. the only question left now is why is chrome doing what it's doing?

edit: turns out combining multiple rotations is less trivial than I thought, but that's not a major issue, as I can just start at the top instead of the bottom.

edit 2: it looks like it only happens with color emoji fonts. when I replaced the emoji font on my device with noto sans symbols, chrome rotated the text elements correctly. I would report the chrome bug, but their bug reporting wizard seems to be broken (gives me a 405 error when I hit submit).

Code: Select all

factorial product enumFromTo 1
isPrime n 
factorial (1) `mod== 1

User avatar
chridd
Posts: 698
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby chridd » Fri Jan 09, 2015 5:20 am UTC

How do I/Is it possible to get a computer running Mac OS X 10.9 to compile a screensaver compatible with Mac OS X 10.6 and higher (I'm currently using Xcode)? I tried changing the deployment target to 10.6, but when I try it on a computer running 10.6 it says that it's not compatible and offers to move the screen saver to the trash (it still works correctly on 10.9). I also found this, but changing GCC_ENABLE_OBJC_GC to "supported" like it suggests just gives an error saying that garbage collection is not supported. The code works fine on 10.5, so it's not an issue of using features that were introduced later.
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics? What phonotactics?) · ze or they · Forum game scores
It's spring; Easter has to be sometime around now, right?
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"

peterbjornx
Posts: 8
Joined: Sat Jan 07, 2012 12:13 am UTC
Location: The Netherlands
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby peterbjornx » Sun Feb 01, 2015 5:09 pm UTC

My ext2 implementation that doesn't seem to be able to write doubly indirect blocks properly and i haven't yet been able to find out why (i've stepped through it dozens of times and can't find the point where it breaks)

http://pastebin.com/rh4Ru8Gh

purtichoudhary
Posts: 1
Joined: Wed Mar 11, 2015 7:16 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby purtichoudhary » Wed Mar 11, 2015 7:20 am UTC

I am working on genetic algorithm for feature selection in Brain MRI image classification using SVM classifier.
I have implemented this code for genetic algorithm but I am not getting correct results. Can someone please tell me what is wrong in my implementation / understanding.. :roll:

Code: Select all

% %%%The following code implements Feature Selection Problem using Genetic
%%%Algorithm.

features=10;
chromosomes=20;
iterations=50;
fitness=zeros(chromosomes,1);
pc=0.8;
pm=0.05;
initialpop1 = zeros(chromosomes,features);
child=zeros(chromosomes,features);
countparent=0;
sp=zeros(iterations,chromosomes);
ac=zeros(iterations,chromosomes);
se=zeros(iterations,chromosomes);
maxfitness=zeros(iterations,1);
num=0;
% population initialization
p=randi([0 1],features,chromosomes);
a=p';

for i=1:chromosomes
   for j=1:features
       initialpop1(i,j)= a(i,j);
   end
end

% Fitness calcultion of initial population
initialpop=initialpop1;
for loop=1:iterations
for i=1:chromosomes
    [sensitivity, specificity, accuracy] = fitness_func(initialpop(i,:));
      number=0;
    for j =1:features
        if (initialpop(i,j)==0)
            number = number+1;
        end
    end
    fitness(i,1) = accuracy + specificity +sensitivity +(0.05*number);
    sp(loop,i)=specificity;
    ac(loop,i)=accuracy;
    se(loop,i)=sensitivity;
end
 parents=zeros(2,features);
 
%Tournament selection
for q=1:chromosomes/2
u=randi([1,features],1,2);
b=randi([1,features],1,2);
q1=u(1);q2=u(2);q3=b(1);q4=b(2);
if(fitness(q1)>=fitness(q2))
    parent(1,:)=initialpop(q1,:);
else
    parent(1,:)=initialpop(q2,:);
end

if(fitness(q3)>=fitness(q4))
    parent(2,:)=initialpop(q3,:);
else
    parent(2,:)=initialpop(q4,:);
end

% one point crossover
p1=parent(1,:);
p2=parent(2,:);
     r2=rand;
        if(r2 < pc)
           
            r3=randi([1,features]);
            child(2*q-1,:) = [p1(1, 1:r3), p2(1, r3 + 1:end)];
            child(2*q,:) = [p2(1, 1:r3), p1(1, r3 + 1:end)];
        else
            child(2*q-1,:) = p1;
            child(2*q,:) = p2;
        end
end
% mutation
for i=1:chromosomes
 r4=rand;
 if(r4 < pm)
     r5 = randi([1,features]);
     if(child(i,r5)==0)
         child(i,r5)=1;
     else
         child(i,r5)=0;
     end
 end

end
initialpop=child;
[p,q]=max(fitness);
maxfitness(loop,1)=p;

end
       
display(maxfitness);
Last edited by phlip on Wed Mar 11, 2015 1:08 pm UTC, edited 1 time in total.
Reason: Added [code] tags

User avatar
Diadem
Posts: 5585
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Thu Mar 12, 2015 11:54 am UTC

I have a silly c++ problem that I feel should be trivial, but I can't figure it out. I was hoping someone here could shine a light on it.

I have made a class. I want a vector of this class. The class in question has a reference as a member variable. How do I do this?

In order to be able to put a class in a vector, the class needs: copy-constructor, assignment-operator, default-constructor (Unfortunately I'm stuck with Visual Studio 2008, so no c++11 move-constructors). The latter two are not a problem, but the first one is. Because I can't make a default constructor with a class that has a reference. A reference needs to be initialized in the constructor, and I have nothing to initialize it with in the default constructor. So I'm stuck.

I could rewrite everything to use pointers instead of references, but that's some work, and also ugly. I'm also confused about the requirements in the first place. Why does vector need a default constructor? There doesn't seem to be a logical reason.

Does anyone know of a solution to this problem?

code example:

Code: Select all

#include <vector>
class A {
public:
    //A() {}  // Not allowed.
    A(int a, int& b)
        : x(a)
        , y(b)
    {}
    int x;
    int& y;
};
int main() {
    int x = 1;
    int y = 2;
    std::vector<A> a;
    a.push_back(A(x, y)); // Not allowed without default constructor.
}
Last edited by Diadem on Thu Mar 12, 2015 12:03 pm UTC, edited 1 time in total.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
phlip
Restorer of Worlds
Posts: 7525
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Thu Mar 12, 2015 12:02 pm UTC

Diadem wrote:I'm also confused about the requirements in the first place. Why does vector need a default constructor? There doesn't seem to be a logical reason.

Because the vector is backed by an array, and the array may be bigger than the vector (to allow it to expand without having to realloc every time). The unused array elements are default-constructed, then the assignment operator is used to populate them when you do a push_back or whatever. Meanwhile the copy-constructor is needed when reallocating the array.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Diadem
Posts: 5585
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Thu Mar 12, 2015 12:07 pm UTC

That makes sense (though in that case why doesn't this requirement exist in C++11?).

But how do I fix this? Is there a solution?
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

operator[]
Posts: 150
Joined: Mon May 18, 2009 6:11 pm UTC
Location: Stockholm, Sweden

Re: The "IT DOESN'T WORK!" thread

Postby operator[] » Thu Mar 12, 2015 12:45 pm UTC

That doesn't sound right. C++ allocators separate allocation and construction; push_back should just do the equivalent of a placement new on uninitialized memory.

The behavior I'm seeing on GCC is that the code does not compile because it's missing an operator=, which gets required by the instantiation of the internal function _M_insert_aux even through it will never actually be called. Adding a dummy operator= makes things compile (although it's not clear what it should do, since you cannot reassign a reference). I presume something similar is happening on Visual Studio - some method or other accidentally gets instantiated and requires the default constructor.

Looking this up in the C++03 standard I have at hand, I see these relevant points:

23.1.3 The type of objects stored in these components must meet the requirements of CopyConstructible
types (20.1.3), and the additional requirements of Assignable types.

20.1.4.1 The default constructor is not required. Certain container class member function signatures specify the
default constructor as a default argument. T() shall be a well-defined expression (8.5) if one of those sig-
natures is called using the default argument (8.3.6).

So apparently GCC is standards compliant, but not MSVC.

Anyhow, the right thing to do here is probably to change to use a pointer instead. Storing references in classes is generally very error-prone, and as we see makes assignment operators and default constructors impossible.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Thu Mar 12, 2015 1:42 pm UTC

I know your VS2008 has a crappy standard library. I suspect it is causing you problems.

A naive push_back is:

Code: Select all

  void push_back( T const& t ) {
    resize( size()+1 );
    back() = t;
  }

the resize() requires a default ctor. We then assign. This requires things you shouldn't require (like default ctor and =), while not using the things you should use (like placement new copy ctor).

As a first guess, I'd guess that VS2008's push_back is something like the above naive one. I would verify if I had an install by stepping through the code. Maybe I'd make a type with a "noisy" ctor and assignments (to the debug console) to ensure I didn't miss them being called.
phlip wrote:Because the vector is backed by an array, and the array may be bigger than the vector (to allow it to expand without having to realloc every time). The unused array elements are default-constructed
That last sentence fragment is false.

vector is backed by an array of uninitialized memory. As it grows, it uses inplace new to construct elements in it.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
phlip
Restorer of Worlds
Posts: 7525
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Thu Mar 12, 2015 2:05 pm UTC

I stand corrected. Evidently my knowledge of C++'s low levels aren't as good as they could be...

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Thu Mar 12, 2015 2:24 pm UTC

When thinking about `std`, it is always best to say "if I was implementing this in C, how would I make it more efficient? Is there any reason we cannot do it in C++?"

Because that is half of the goal of `std` -- provide high level abstract interfaces to really low-level high performance code.

Now, `std` screws up sometimes; the lack of a "push_back, do not check capacity, I guarantee you have the capacity, really" is an example. (In theory, the optimizer can detect this: in practice, they can easily fail.) Also, the lack of a realloc equivalent is annoying. (really, I'd want a lower level realloc, one that doesn't deallocate: "given this allocation, can you extend it by some value between A and B?") I could write a significant improvement to std::vector with that. Hmm.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Jplus
Posts: 1686
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Jplus » Fri Mar 13, 2015 7:59 am UTC

Yes, allocators are treated too much like a black box in the standard. Alex Stepanov has written about that too.

Diadem: as an alternative to using pointers instead of references or switching to a better compiler (which I understand is not an option), you could also reach for third-party container implementations. For example, have a look at Boost.Container. Yet another option would be to use smart pointers instead of references, depending on the semantics of what you're trying to do. In that case it would again be advisable to use a third-party implementation like Boost's, since auto_ptr is almost never what you want.

purtichoudhary: I might have a look at your issue tomorrow.
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
Diadem
Posts: 5585
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Fri Mar 13, 2015 12:22 pm UTC

I ended up using a pointer.

So now I have a constructor that takes a reference, and a getter function that returns a reference, but internally it's stored as a pointer. I guess that's acceptable, it's encapsulated well, and it's a small class. Just have to make sure to not accidentally deep-copy or delete it.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

Blutkoete
Posts: 3
Joined: Mon Oct 14, 2013 5:26 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby Blutkoete » Mon Apr 20, 2015 8:35 am UTC

I once wrote a program for a PLC and it drove me mad because after some refactoring, the compiler complained about a variable declaration of mine. After staring on it for one hour or so, I went home, just to wake up in the middle of the night and realize what the compiler didn't like about the line

Code: Select all

unsigned int packetCount = -1;
.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Tue Apr 21, 2015 12:51 pm UTC

Blutkoete wrote:I once wrote a program for a PLC and it drove me mad because after some refactoring, the compiler complained about a variable declaration of mine. After staring on it for one hour or so, I went home, just to wake up in the middle of the night and realize what the compiler didn't like about the line

Code: Select all

unsigned int packetCount = -1;

what? That line looks fine to me -- max unsigned int?
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
applepi
Posts: 19
Joined: Sat Oct 17, 2015 2:30 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby applepi » Sun Oct 18, 2015 5:41 pm UTC

I'm in a bit of a conundrum, and I have a feeling the solution will probably be stupidly simple, making me wonder why I couldn't've figured it out.
I'm programming in C++ (using Xcode 6.2). Because I've just given up on trying to make the MYSQL connector work for now, I'm using a text-file system as a temporary solution. It's probably very inefficient and overly complicated, but it's like I said, it's temporary.
For the life of me, I can not get these file searching functions to work. I've tested all of them isolated and they work FINE. When put together? It refuses to work for me. Here's the main text-file search function. This works sometimes, but gives me more trouble then I'm thinking it's worth.

Code: Select all

bool findKey(fstream &fileToSearch, string key) // Returns true if the key is found in a text file
{
    bool wasItFound = false;
    vector<string> temp; // Temporary vector. We'll read our file into it, then forget about it. We do this so we can search the vector.
   
    fileRead(fileToSearch, temp); // Reading
   
    if (findKey(temp, key)) // Searching
    {
        wasItFound = true; // Yay, we found it!
    }
    else // If we didn't find it
    {
        // Error code 001
    }

    return wasItFound;
}


Here's the vector search function

Code: Select all

bool findKey(vector<string> vectorToSearch, string key) // Returns true if the key is found
{
    bool wasItFound = false;
   
    for (int i = 0; i < vectorToSearch.size(); i++) // Cycle through the vector
    {
        if (vectorToSearch[i].find(key) != string::npos) // If the key is found before the end of the string
        {
            wasItFound = true; // It's true because the key we were looking for has been found
            break; // We can break out of the loop because our job is done here.
        }
        else
        {
            // Error code 001
        }
       
    }
    return wasItFound;
}


Here's the fileRead function

Code: Select all

void fileRead(fstream &myFile, vector<string> &fileText) // Reads lines from a file into a string vector, then erases empty
{                                                       //  strings from the string vector.
    if (myFile.is_open())
    {
        for (int i = 0; !myFile.eof(); i++)
        {
            // We wouldn't want memory errors now, would we?
            resizer(fileText, 1);
           
            getline(myFile, fileText[i]); // Reading lines from the file into the vector
        }
       
        //myFile.close(); // It's job here is done.
       
        for (int ii = 0; ii < fileText.size(); ii++) // Looping through the vector...
        {
            if (fileText[ii].empty()) // Checking if there are any empty strings so we can...
            {
                fileText.erase(fileText.begin()+ii); // Erase them!
            }
        }
    }
    else
    {
        // Error code 002
    }
}


Here's the resizer function

Code: Select all

void resizer(vector<string> &stuff, int expandSize) // Takes in a string vector, and resizes it by the amount stored
{                                                  //  in the second parameter.
    int temp = stuff.size() + expandSize;
    stuff.resize(temp);
}


Here are the contents of userInfo.txt

Code: Select all

Name:

Relationship: 3

Interests:

Likes:

Loves:

Dislikes:

Hates:

Typing Speed: 94


Here are the enumerated types of "Relationship" the user can have with the program

Code: Select all

enum relationship
{
    STRANGERS,
    FRIENDS,
    FLIRTATIONSHIP,
    LOVE,
};


Here's the call using all of these functions that DOESN'T WORK??

Code: Select all

if (findKey(userInfo, to_string(STRANGERS))) // If they're strangers to MathBot, MathBot will have to find out their name
    {
        typewriter("Success!", typingSpeed);
    }
    else if (findKey(userInfo, to_string(FLIRTATIONSHIP)) || findKey(userInfo, to_string(LOVE))) // If our user is okay with us flirting
    {
        canFlirt = true; // We can flirt
    }

I can get it to say "Succes!" when I put "0" in the file, but when I put 2 or 3 (the values of flirtationship and love), it doesn't return true at all.

Here is how I tested the functions on their own (warning - super sloppy)

Code: Select all

//to_string test
    if (to_string(FLIRTATIONSHIP) == "2" && to_string(LOVE) == "3")
    {
        cout << "to_string if statement worked!" << endl;
    }
    else
    {
        cout << "to_string if statement did not work as expected!" << endl;
    }
// fileRead test
    fstream userInfo ("userInfo.txt");
    vector<string> deleteme;
    fileRead(userInfo, deleteme);
    for (int i = 0; i < deleteme.size(); i++)
    {
        cout << deleteme[i] << endl;
    }
   
    // findKey test
    findKey(userInfo, "Name");
    if (findKey(userInfo, to_string(LOVE)) && findKey(userInfo, "3") && findKey(deleteme, to_string(LOVE)) && findKey(deleteme, "3"))
    {
        cout << "they all work?" << endl;
    }
    else if (findKey(userInfo, to_string(LOVE)))
    {
        cout << "1. worked" << endl;
    }
    else if (findKey(userInfo, "3"))
    {
        cout << "2. worked" << endl;
    }
    else if (findKey(deleteme, to_string(LOVE)))
    {
        cout << "3. worked" << endl;
    }
    else if (findKey(deleteme, "3"))
    {
        cout << "4. worked" << endl;
    }
    else
    {
        cout << "none worked" << endl;
    }
    // 3 and 4 work.

    // resize test
    vector<string> resizeTest;
    cout << resizeTest.size() << endl;
    resizer(resizeTest, 1);
    cout << resizeTest.size() << endl;


I purposely use variable names I find simple or way too self explanatory most of the time, and throw in jokey/sarcastic sounding comments since it's my own solo project.

I'm self taught, and a novice, so please go easy on me lol...

(Oh, and just for context, because I know all of this may seem super weird without it - I'm working on a "creepy" math tutor program. See, it all started as a joke, but then I decided it'd be nice practice and an easy idea to work on since I'm a pick up line/pun master. Basically, it'll do math, but will also try to hit on ((in a really dork-y, johnny bravo esque way)) the user, if they're okay with it.)

User avatar
Flumble
Posts: 1698
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby Flumble » Sun Oct 18, 2015 8:47 pm UTC

How does your test run compile though? Sometimes you correctly feed a file stream (userInfo) to findKey and other times you feed it a vector (deleteme, not a very good name either). :shock:

Since you're a novice and you're still open to ideas, I'll start by saying it out loud: you're doing it all wrong. :lol:
With that, I'm mainly targeting your tendency to write a lot of code yourself instead of looking what the language can offer you, or generic code that others have written. Oh and also the way you call a function findKey when you're actually searching for a substring and you're passing it a value every time instead of a key.
The way you're passing around containers is nice though.

Anyway, let's find out what you actually want. My guess is that you want to have a fixed set of properties for a given user and do stuff with the values of those properties. Is this correct?

A set of properties (or named values) can be stored in a map, or better yet, a class. The nice thing about a class is that the properties are not only named, but also typed (so you can e.g. compare the values of the enum instead of converting them to strings), checked during compilation (so misspelled and non-existing names show up as errors) and your editor will be much more helpful in general.

Now the hard part is loading text data into such a class. Since C++ can't automagically generate code to convert an object to text and back, the second best thing is using a library to make it work. cereal is probably the easiest way. For example:

Code: Select all

#include <iostream>
#include <fstream>
#include <cereal/archives/json.hpp>

class UserInfo {
public:
  string name;
  relationship relationshipStatus; //it's your fault for calling the enum itself relationship
  string interests, likes, loves, dislikes, hates;
  unsigned int typingSpeed;

  //specifying how the data must be serialized is just a matter of adding some magic code:
  template<class Archive> void serialize(Archive& archive) {
    archive(CEREAL_NVP(name), CEREAL_NVP(relationshipStatus), CEREAL_NVP(interests), CEREAL_NVP(likes), CEREAL_NVP(loves), CEREAL_NVP(dislikes), CEREAL_NVP(hates), CEREAL_NVP(typingSpeed));
  }
};

int main() {
  ifstream userFile("userInfo.txt");
  cereal::JSONInputArchive archive(userFile);

  UserInfo user;
  archive(user);

  if (user.relationship_status == LOVE)
    cout << "Success!" << endl;

  return 0;
}

It does require a slightly different userInfo.txt file:

Code: Select all

{
  "user": {
    "name": "",
    "relationshipStatus": 3,
    "interests": "",
    "likes": "",
    "loves": "",
    "dislikes": "",
    "hates": "",
    "typing speed": 94
  }
}

(I haven't tested any of this, but I presume the enum value will be saved as a number.)

User avatar
applepi
Posts: 19
Joined: Sat Oct 17, 2015 2:30 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby applepi » Mon Oct 19, 2015 2:00 am UTC

Oh! findKey is overloaded to handle file streams and vectors. I probably forgot to mention that. Haha, deleteme isn't the best name, I just did that so I could easily find all the test code and erase it.

Thank you so much for all of the helpful advice, and for being very kind about it! I really really appreciate it. I was thinking it'd be a better idea to have a userInfo class, but I programmed it all backwards. If I showed you the full code, you'd probably cringe at how it's structured. Instead of giving userInfo a class, I gave the mathbot a class of it's own, and passed the user's info through to change how mathbot functions. Really, the more organized way would to just give them their own classes, right? I have to go through and move around a few things. I was a little hesitant to throw so many classes into the mix because one of my last programming projects had a whole handful of classes that all cross referenced each other, which became confusing and overwhelming.

I've never really thought about looking at what others have written, or really deeply exploring what the language has to offer so I can take advantage of it. I've sort of just Googled as I needed, and if it didn't come up right away in the standard library then I'd just try to build it myself. I'm definitely going to take your advice though - because if there's an easier way to do it, I might as well take advantage. :D

Anywho, Cereal seems absolutely fantastic! Thank you for the recommendation. I'm going to try it everything out tomorrow, and tell you how it goes.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11018
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Mon Oct 19, 2015 2:18 pm UTC

The part where you remove blank lines: use the remove_if-erase idiom. It is linear, instead of quadratic.

You copy the std::vector, instead of taking it by const&, on one function. That is expensive.

Plus, C++11 it:

Code: Select all

// Returns true if the key is found
bool findKey(std::vector<std::string> const& search_this, std::string const& key)
{
  for (std::string const& str : search_this)
    if (str.find(key) != std::string::npos) // If the key is found before the end of the string
      return true;
  return false;
}

There are advantages to braces and your flow control style. But there are also advantage to doing exactly 1 thing on each line, and reducing the number of lines.

Similarly, change `fileRead` to return the `std::vector`. Then `findKey` becomes:

Code: Select all

// Returns true if the key is found in a text file
bool findKey(fstream &fileToSearch, string const& key)
{
  std::vector<std::string> temp = fileRead(fileToSearch);
  return findKey(std::move(temp), key);
}

again, 1 thing per line. (I would reduce it to a 1 liner, the thing that line does is "change the parameter fileToSearch into a vector, and recurse", but that is pushing it).

Second, your question:
applepi wrote:I can get it to say "Succes!" when I put "0" in the file, but when I put 2 or 3 (the values of flirtationship and love), it doesn't return true at all.

The code you quoted doesn't do anything on that branch besides setting a bool. What it does with a bool is something you haven't told us, and yet it is something you say you are having problems with.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Flumble
Posts: 1698
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby Flumble » Mon Oct 19, 2015 3:45 pm UTC

Yakk wrote:The part where you remove blank lines: use the remove_if-erase idiom. It is linear, instead of quadratic.

Not only that, but every time the it (=the manual implementation) erases one element, it skips over the next one. And all of it can be avoided by not putting blank lines in the vector in the first place. (also, to append elements to a vector, simply use the append method instead of resizing the vector and replacing the last element)

applepi wrote:Oh! findKey is overloaded to handle file streams and vectors. I probably forgot to mention that.

I figured as much. The alternative would be that the compiler (nowadays) is too stupid to discern vectors from streams.

applepi wrote:Thank you so much for all of the helpful advice, and for being very kind about it! I really really appreciate it. I was thinking it'd be a better idea to have a userInfo class, but I programmed it all backwards. If I showed you the full code, you'd probably cringe at how it's structured. Instead of giving userInfo a class, I gave the mathbot a class of it's own, and passed the user's info through to change how mathbot functions. Really, the more organized way would to just give them their own classes, right? I have to go through and move around a few things. I was a little hesitant to throw so many classes into the mix because one of my last programming projects had a whole handful of classes that all cross referenced each other, which became confusing and overwhelming.

Ah, good, so you're already familiar with classes. Yes, structuring your data* in classes (or table columns, going back to your original idea of using SQL) nearly always helps to organize your code.
Unfortunately, I don't have any tricks to untangle a cross-referencing mess, other than: try writing down a diagram of your classes with all their properties and relations to other classes. Hopefully it lets you keep a confident overview of your program and figure out which references are unnecessary. I'll restrict you to UML notation so you don't have to bother about thinking up a notation.
But for now, get that mathbot running so you get positive feedback from programming. :D


*not necessarily the functions, but that often comes naturally when a function is used by one class only and turns out to be a process for that class specifically.

User avatar
applepi
Posts: 19
Joined: Sat Oct 17, 2015 2:30 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby applepi » Fri Oct 23, 2015 9:11 pm UTC

Thank you for the tips and reply! I appreciate it. Everything looks a lot cleaner, and easier to understand.

It's supposed to set a bool canFlirt to true, which would affect the way the program runs. I haven't gotten that far yet. The only way that I know that if statement doesn't work as intended, is I tried testing it with a temporary cout statement. I couldn't get it to cout, which means it wasn't returning true (it couldn't find numbers that weren't 0).

Now, I tried just plopping your code in, Yakk (I know copy and pasting is a sin, but I was impatient and excited to test it out. Of course, I did make a few changes so that it would work without errors), but I keep getting the message, "Undefined symbols for architecture x86_64:
"fileRead(std::__1::basic_fstream<char, std::__1::char_traits<char> >&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&)". I've had errors like this in the past, but they had obvious fixes (something in the header file not matching up with the cpp file), however I can't seem to figure out what's causing this to happen? I can provide the code I have, if you'd like.

As for cereal, I absolutely love it! It works like a charm, and I'm excited to use it. I don't mind having a different format for my txt file, it has a very organized look anyways.

A diagram is a really good idea. I had thought about doing one, but never did. I'm going to work on a map, then restructure my project so it's easier to manage and work on.

Thank you both so much for everything! I'm excited to make progress on my project. :)


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 3 guests