• 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

hateradio

The Most Dangerous Yes Man
I'm running into an issue with a JavaScript program I've been working on in my spare time. The concept is that the program will draw a "pixel grid" on the screen then later on iterate through and change the color of the "pixels" based on various parameters.
Why don't you just store it as a matrix?

Code:
function pixelMatrixGenerator(numRows, numCols) {
  var i, j, matrix = [];
  for (i = 0; i < numRows; i++) {
    matrix[i] = [];
    for (j = 0; j < numCols; j++) {
      // create a new pixel (just the color) at the given coordinate
      matrix[i][j] = "#000000";
  }
  
  return matrix;
}

var grid = pixelMatrixGenerator(WIDTH, HEIGHT);

// now you can access a pixel by the given coordianate

console.log(grid[3][5]); // x -> 3, y -> 5

Now you can cycle through grid (independent of heights and widths) and draw the pixels. You can also later update the grid, and draw it again.
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
Why don't you just store it as a matrix?

Now you can cycle through grid (independent of heights and widths) and draw the pixels. You can also later update the grid, and draw it again.

This would probably work with some tweaking, but it's doing essentially the same job that my code is doing currently. Storing the pixel information. I previously was using a matrix style two-dimensional array to store the pixel data, but switched to a one dimensional array of objects for simplicities sake.

My concern is that the objects are being overwritten somehow with the final pixel's value. I'd like to stick with the array of objects set up that I have currently if possible.

This is my console log during creation.
GW3cI5H.png
And after when accessed in the start() function.
450:960 is the final coordinate on the grid.
There are 330 pixels total, and while creating every pixel object has the correct data. When accessing the pixels[] array from the start() function though, each object contains 450:960.
 

Chris R

Member
EDIT: I got it! Thank you very very much.

Code:
 //If it's a default constructor call Withdrawal method to determine if you are eligible to withdraw.
       if(nSelection == 1 && bankEmpty.makeWithdrawal(dWithdrawalAmount) == true){
       
      System.out.println("Withdrawal successful");
           System.out.println("");
       }//end if
       

       else if(nSelection == 1){
           
           System.out.println("Insufficient funds. Withdrawal not made.");
           System.out.println("");
           
       }
Works :)

That works, but it might be better to do something like this...

Code:
if (nSelection == 1) {
    if (bankEmpty.makeWithdrawal(dWithdrawalAmount)) {
        //withdraw worked!
    } else {
        //failure!!!
    }
}

Just to be clean and easy for you to read in the future.
 

Vire

Member
That works, but it might be better to do something like this...

Code:
if (nSelection == 1) {
    if (bankEmpty.makeWithdrawal(dWithdrawalAmount)) {
        //withdraw worked!
    } else {
        //failure!!!
    }
}

Just to be clean and easy for you to read in the future.

Thanks again, I really appreciate the help. That was the last little hangup in my program, I have everything else working like a charm.
 

hateradio

The Most Dangerous Yes Man
This would probably work with some tweaking, but it's doing essentially the same job that my code is doing currently. Storing the pixel information. I previously was using a matrix style two-dimensional array to store the pixel data, but switched to a one dimensional array of objects for simplicities sake.

My concern is that the objects are being overwritten somehow with the final pixel's value. I'd like to stick with the array of objects set up that I have currently if possible.

This is my console log during creation.
And after when accessed in the start() function.
450:960 is the final coordinate on the grid.
There are 330 pixels total, and while creating every pixel object has the correct data. When accessing the pixels[] array from the start() function though, each object contains 450:960.
That's because you're referencing the pixel variable and modifying it.

Code:
// new object
var a = {one: 1};

// b <- a
var b = a;
b.one = 1.1

// so now . . .
console.log(a);
// {one: 1.1}

You're basically doing that with pixel. So you can do two things. Create a Pixel constructor to create new pixels (or a function that returns an base pixel object) or simply make the new object inline.

Code:
        pixels[i] = {
            rowPos : pixelRowPos,
            colPos : pixelColPos,
            color : colors[colorIndex]
        };

Storing the position and column would be unnecessary if you did it the matrix way. You could just multiply the row/column by the width/height and get the position.
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
That's because you're referencing the pixel variable and modifying it.

Code:
// new object
var a = {one: 1};

// b <- a
var b = a;
b.one = 1.1

// so now . . .
console.log(a);
// {one: 1.1}

You're basically doing that with pixel. So you can do two things. Create a Pixel constructor to create new pixels (or a function that returns an base pixel object) or simply make the new object inline.

Code:
        pixels[i] = {
            rowPos : pixelRowPos,
            colPos : pixelColPos,
            color : colors[colorIndex]
        };

Storing the position and column would be unnecessary if you did it the matrix way. You could just multiply the row/column by the width and get the position.

Damnit, I am an idiot. Thanks for pointing the constructor part out. I think that will fix it.

I get what your saying about the matrix. Right now it's easier for me to utilize this object setup. In the future when I scale this up I might switch.
 
I have a question that is not quite a programming issue, but is programming related.

I am building an Android application that interfaces with a PHP API I built. I have about 4 API calls, but only one of them changes regularly (about every 15 minutes). So the other three I can call once and cache it to the device, but the 4th one I can't.

This API is hosted on a Dreamhost account. I am not expecting much traffic to the application once it releases honestly, but just in case, I would hate for my shared host to go down. Do any of you have any clue if Dreamhost will be able to support the API? And if not, what kind of server do you think would suffice?
 

peakish

Member
I have a question about C memory, I'm still quite bad at it. I got interested in writing a recursive function which would remove specific characters from input strings. It takes (and returns) a char * argument. My idea was that I'd use memmove to shift the string characters around in it's memory location (originally I tried using strcpy but that couldn't copy overlapping memory).

The function seems to work if I create char pointers and copy strings into them, but fails if I explicitly set a string in the code (char *str = "This is a string" way). But, am I not in both cases sending in a pointer containing the address of the string in memory? Does it fail because the explicit string strlit (is it called string literal, btw?) is allocated on the stack of main, while the pointer strptr is alloc'd on the heap by strdup?

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *strip(char *string)
{
    if (string == NULL) {
        return "";
    }

    char *tail = string + 1;

    switch (*string) {
        case '\0':
            return "";
            break;

        case '\n':
        case ' ':
            return strip(tail);
            break;

        default:
            memmove(tail, strip(tail), strlen(tail));

            return string;
            break;
    }
}

int main(int argc, char *argv[])
{
    char *strptr = strdup("Test of one string.\n");
    char *strlit = "This is another string.\n";

    printf("Using memory allocation: %s\n", strip(strptr));
    printf("Using string literal (?): %s\n", strip(strlit));

    free(strptr);

    return 0;
}

Code:
$ ./main
Using memory allocation: Testofonestring.
Segmentation fault (core dumped)
 

tuffy

Member
String constants may be stored in read-only memory that you don't have access to modify, which leads to segfaults if you try. Whereas if you initialized it as an array with memory provided from the stack, like:
Code:
char strlit[] = "This is another string.\n";
your program should execute successfully.
 

peakish

Member
String constants may be stored in read-only memory that you don't have access to modify, which leads to segfaults if you try. Whereas if you initialized it as an array with memory provided from the stack, like:
Code:
char strlit[] = "This is another string.\n";
your program should execute successfully.
Oh, so initialising a string in that way is simply doing it wrong then (given that it should be variable)? Good to know. Thanks!
 

poweld

Member
Oh, so initialising a string in that way is simply doing it wrong then (given that it should be variable)? Good to know. Thanks!

Modifying a string literal in C is undefined behavior.

Man, I do not miss C and C++ for their many instances of undefined behavior.
 

tuffy

Member
Modifying a string literal in C is undefined behavior.

Man, I do not miss C and C++ for their many instances of undefined behavior.
The virtue of undefined behavior is that a language implementor can use that flexibility to make things more efficient than might be possible otherwise. For instance, a C's function call can evaluate its arguments in any order, so a compiler author can just pick whatever order happens to be fastest.
 

Ya no

Member
I need to write a SQL insert statement for an assignment and I'm not sure why this isn't working:

Code:
INSERT INTO terms VALUES
(DEFAULT, 32,'AX-014-027','2011-08-01', 434.58, 0, 0, 2, '2011-08-31', NULL)

It specifically says to do it without using a column list. The first column is invoice_id and it says the value should be the next automatically generated ID. I wasn't sure how to do that so I tried DEFAULT. Is that where my problem is?

EDIT: Yeah I'm an idiot I was trying to insert the data into the wrong table.
 

poweld

Member
The virtue of undefined behavior is that a language implementor can use that flexibility to make things more efficient than might be possible otherwise. For instance, a C's function call can evaluate its arguments in any order, so a compiler author can just pick whatever order happens to be fastest.

I'm with you in spirit, but your argument sounds a little like something Andrew Ryan would say :)

I just want my shitty code to behave "normally" at this point. I don't want to discover the dark designs of the compiler's architect when I bump into something in the dark.

Maybe I'm just getting old...
 

tuffy

Member
I'm with you in spirit, but your argument sounds a little like something Andrew Ryan would say :)
I'm sure none of us want 2 + 2 to equal 5 just to make the compiler's job easier, but nobody wanted a repeat of the ALGOL 68 mess where compiler authors had a hell of a time implementing the thing either. So C and its contemporaries took a much looser design approach that's worked out pretty well in practice overall, even if it makes a programmer's job harder on occasion.
 

Anustart

Member
I don't understand what I'm supposed to do here. I need to write code to get the longest string from a binary tree. The code:

Code:
string largest(BSTNode *current) // recursive version
		{
			if (current == NULL) return NULL;  // base case -- no tree

			cout << "largest: this data is " << current->getD() << endl;
			
			if (*right == NULL) // Base case: no right subtree...
			{
				cout << "largest: going to return " << current->getD() << endl;
				return current;  // ... so this node's value is largest
			}
			else
			{
				cout << "largest: going to recurse " << endl;
				return ??????????????????????  // recurse to the right subtree
			}

		} // end largest

I'm having trouble understanding what to replace those ? marks with. How can I recurse through a binary tree that can have a node that has two others attached to it? Is this really only a single line of code?

Edit: Nevermind, largest value is going to be the right most node, so I would just return largest(current->getR()) if I'm understanding it correctly.

Edit: Nope, largest isn't the right most, code is fucked.

Final Edit: My professor's provided code was fucked. In his insert function, he was determining whether a string was less than another by doing if (string <= string). I do not even know what that is comparing. When I changed his code to compare the length of each string, it worked. Well, if size is being compared. What is compared naturally if you ask if word < other word?
 

Quasar

Member
So I'm struggling a bit with some linq to sql queries in C#.

I have a SQL query that works fine.

Code:
select distinct Patient.patientID,Patient.patientFirstName,Patient.patientLastName 
from Patient,Admission
where Patient.patientID = Admission.admissionPatient and 
Patient.patientID <> 
(select Admission.admissionPatient from Admission
RIGHT JOIN Operation
on Admission.admissionID = Operation.operationAdmission)
;

Now I have a linq query that works except for the NOT

Code:
                    var adList = (from ad in db.Admissions join op in db.Operations on ad.admissionID equals op.operationAdmission select new { ad.admissionPatient }).ToList();
                    var patList = (from pat in db.Patients join ad in db.Admissions on pat.patientID equals ad.admissionPatient select pat).ToList();

                    var query = (from ad in adList 
                                 from pat in patList
                                 where ad.admissionPatient == pat.patientID
                                 select new
                                 {
                                     pat.patientID,
                                     pat.patientFirstName,
                                     pat.patientLastName,
                                     pat.patientDOB,
                                     pat.patientPhone,
                                     pat.patientEmail,
                                     pat.patientContactPhone,
                                     pat.patientContactName
                                 }


                                )
                                .GroupBy(g => new {g.patientID,g.patientFirstName,g.patientLastName,g.patientDOB,g.patientPhone,g.patientEmail,g.patientContactPhone,g.patientContactName})
                                .Select(s => s.FirstOrDefault());

Now simply changing the == to a != did not work and I tried changing the where line to ''where !ad.admissionPatient.Equals(pat.patientID)' which with both fields integers I thought might work.

How exactly do you do NOTs with linq?
 

Slavik81

Member
Any recommendations on how to add audio to a freeglut program? Something as simple as "start playing this *.wav" and "stop playing this *.wav" would be wonderful, but I can live with a bit of complexity if need be.

FreeGLUT / Linux / C++. Though, Windows, OSX and C compatability are nice bonuses.

Thanks. Am I getting closer..? I talked to a few classmates today and it seems I'm not the only one having a lot of trouble with this, which makes me feel a bit better :p

Code:
void String::append(const String &str)
{
	char *new_contents = new char[(len + str.len) + 1];		

	strcpy(new_contents, contents);
	strcat(new_contents, str.contents);

	delete [] contents;

	contents = new_contents;
	
}

Actually, I just realized this code causes the program to crash right after I finish entering what I want to append.
That's exactly what I was hinting at, but I was mistaken about there being only two more changes required. There's one more thing to do.

I was a bit thrown off by your use of strcat and strcpy. Those are typically only used when you aren't also storing the length of the string. If you do know the length, you can use memcpy. I wouldn't bother changing them for this assignment, but just so you know.

As for why it's crashing. I'm not sure exactly what your problem is, but I have a suspicion. Your code right there works fine in a simple program with a single append. However, until you address the last issue, multiple appends to the same string are going to result in a buffer-overflow.

Hint: your mistake relates to len.
 

RELAYER

Banned
I have my microprocessor midterm tomorrow. The instructor uploaded some old tests online for practice, but he says he won't give us the solutions. I've completed one and it all seems to be pretty basic programming stuff. Sorry for the megapost, but I would be grateful if anyone would look over my answers.

There is one part in particular, Problem 3 part C, that I don't know how to do and could use some help.

Problem 1 said:
A strain gauge is being used to measure the weight of letters to determine the proper postage due. The strain gauge is connected to pin 18 on the mbed module and outputs a voltage of 0.15 volts per ounce weight. The mbed will then use its on-board LED1, LED2, and LED3 to indicate the weight range of a letter.

a) Write the C++ declarations needed for the mbed class objects used.

Code:
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

AnalogIn straingauge(p18);

b) Write a function that samples the strain gauge output 1000 times and computes the mean average weight in ounces. Leave this weight in the variable W.

Code:
int main () {
   while (1) {
   average = 0;
      for (int i = 0; i < 1000; i++) {
      array[i] = straingauge.read();
      }
      for (int i = 0; i < 1000; i++) {
      average = average + (array[i]/1000);
      }
   W = average * 0.15;
   }
}

c)Write a function that uses the weight stored in variable W and updates the LEDs according to this table:
8CXLIJg.png


Code:
if (W <= 0.1) {
led1 = 0;
led2 = 0;
led3 = 0;
}
else if (0.1 < W <= 1.0)
led1= 1;
led2 = 0;
led3 = 0;
}
else if (1.0 < W <= 2.0) {
led1 = 1;
led2 = 1;
led3 = 0;
}
else if(2.0<W) {
led1 = 0;
led2 = 0;
led3 = 0;
}

Problem 2 said:
An optical sensor is monitoring parts passing by on a conveyor belt in a factory. The output of this sensor is a logic high when a part is detected and low otherwise. It is connected to pin 30 on the mbed module. Every minute, the mbed should report the number of parts detected in the past minute to a computer via the USB serial connection. To ensure that all parts are properly counted, the count should be updated via an interrupt.

a) Write the C++ declarations needed for the mbed class objects used as well as the count variable.

Code:
InterruptIn sensor(p30);
volatile int count;

b) Write an interrupt service routine (ISR) function that updates the count.

Code:
void sensorcount (void) {
count++;
}

c) Write the instructions that enables the function in part b to be called automatically when a part is detected.

Code:
int main() {
sensor.rise(sensorcount)
}

Problem 3 said:
An mbed module is connected to two switches as shown in this schematic. These two switches will control the mbed's LED1.
BBr2yN0.png


a) Write the C++ declarations needed for the mbed class object used.
Code:
DigitalOut led1(LED1);
DigitalIn switch15(p15);
DigitalIn switch16(p16);

b) Pull-up or pull-down resistors are needed to reliably detect a switch in the off/open state. Write the instructions needed to activate the appropriate resistors types for the two switches.

Code:
pin15.mode(PullUp);
pin16.mode(PullDown);

c) Write the instructions needed so that LED1 is on if, and only if, both switches are in the on/closed position.

Code:
// this part i don't know how to do. i've never had to implement an if clause that requires two conditions. so i'm unsure of the proper way to do this

Problem 4 said:
The following code is part of a program that implements a filter using digital signal processing -

Code:
AnalogIn ain(p20);
AnalogOut aout(p18);
float x0, x1, x2;

void dsp (void)
{
   float y;
   x2 = x1; x1 = x0; x0 = ain.read();
   y = 0.25 * x0 + 0.5*x1 + 0.25*x2;
   aout.write(y);
}

The dsp function should be called automatically at a frequency of 16000 times per second. Write the C++ declaration for the mbed class object needed and the instruction that enables the dsp function to be called automatically at this frequency.

Code:
Ticker tick;

tick.attach(16000, dsp);

b) Another way to implement the above code is:

Code:
AnalogIn ain(p20);
AnalogOut aout(p18);
int x0, x1, x2;

void dsp (void)
{
   int y;
   x2 = x1; x1 = x0; x0 = ain.read_u16();
   y = (x0 + 2*x1 + x2)/4;
   aout.write_u16(y);
}

Is this more efficient or less efficient than the first version? Justify your answer.

// no idea. The main difference seems to be that instead of using the ticker, the 2nd code is just reading and writing more frequently. No idea how this affects efficiency.
 
That's exactly what I was hinting at, but I was mistaken about there being only two more changes required. There's one more thing to do.

I was a bit thrown off by your use of strcat and strcpy. Those are typically only used when you aren't also storing the length of the string. If you do know the length, you can use memcpy. I wouldn't bother changing them for this assignment, but just so you know.

As for why it's crashing. I'm not sure exactly what your problem is, but I have a suspicion. Your code right there works fine in a simple program with a single append. However, until you address the last issue, multiple appends to the same string are going to result in a buffer-overflow.

Hint: your mistake relates to len.

I did realize I needed to update length for multiple appends, so this is what my code looks like now.

Code:
void String::append(const String &str) 
{
	
	char *new_contents = new char[(len + str.len) + 1];		
	
	strcpy(new_contents, contents); 
	strcat(new_contents, str.contents);
	
	//delete [] contents;
	
	contents = new_contents; // contents now points to new_contents
	len += str.len; // length is updated

}
Everything seems to be appending correctly now, aside from the first appending a string twice for some reason.
My newest problem is that destroying contents (either here or in the destructor) crashes the program, so I'll have to work on that tonight.
 

Zoe

Member
So I'm struggling a bit with some linq to sql queries in C#.

I have a SQL query that works fine.

Code:
select distinct Patient.patientID,Patient.patientFirstName,Patient.patientLastName 
from Patient,Admission
where Patient.patientID = Admission.admissionPatient and 
Patient.patientID <> 
(select Admission.admissionPatient from Admission
RIGHT JOIN Operation
on Admission.admissionID = Operation.operationAdmission)
;

Well first of all I would clean up that query because it seems unnecessarily messy. Why are you using a join in the where clause but not the from? Why are you using a right join?

I would do something like
Code:
select distinct 
	Patient.patientID
	,Patient.patientFirstName
	,Patient.patientLastName 
from 
	Patient
join 
	Admission on Patient.patientID = Admission.admissionPatient
where 
	Patient.patientID not in (
		select
			Admission.admissionPatient
		from
			Admission
		join
			Operation on Admission.admissionID = Operation.operationAdmission
		)

I couldn't tell from the context whether the first join was actually necessary. If a patient only appears in the patient table once there's an admission record, I would think it's not.

Then to translate into Linq: http://stackoverflow.com/questions/183791/how-would-you-do-a-not-in-query-with-linq
 

Slavik81

Member
I did realize I needed to update length for multiple appends, so this is what my code looks like now.

Code:
void String::append(const String &str) 
{
	
	char *new_contents = new char[(len + str.len) + 1];		
	
	strcpy(new_contents, contents); 
	strcat(new_contents, str.contents);
	
	//delete [] contents;
	
	contents = new_contents; // contents now points to new_contents
	len += str.len; // length is updated

}
Everything seems to be appending correctly now, aside from the first appending a string twice for some reason.
My newest problem is that destroying contents (either here or in the destructor) crashes the program, so I'll have to work on that tonight.
Make sure you've followed the 'rule of 3'. You need to redefine the assignment operator, copy constructor and destructor. The first two should be doing deep copies. The destructor should be releasing memory.
 
Make sure you've followed the 'rule of 3'. You need to redefine the assignment operator, copy constructor and destructor. The first two should be doing deep copies. The destructor should be releasing memory.

Hmm, I do have my copy constructor and assignment operator defined but I must have screwed something up in one of them. I'll take a look at my code in a bit. Thanks again for your help by the way. My assignment is due tomorrow so hopefully I can figure this out before then.
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
One more question about this program I'm writing.

I'd like to have this set up to run on a server continuously. So that you can go to the webpage and see the current status of the pixel grid.

I've started working with Node.js and Express.js in order to get a simple web file server up and running. Right now it's only providing the static page with the grid starting out at the beginning each time you go to the page.

Does Node.js or Express.js have the capability to keep a js program running continuously on a server like I was looking for? Is this even possible, or am I chasing an incorrect goal.

My other idea was to store the state (this is stored already, but not used in this way) and serve that each time the page was requested. That would allow it to "start back up" where it last left off, but it would still only be iterating through while you have the page open.

I'm very, very new to web serving and the like, so if I'm being an idiot let me know.
 
Any recommendations on how to add audio to a freeglut program? Something as simple as "start playing this *.wav" and "stop playing this *.wav" would be wonderful, but I can live with a bit of complexity if need be.

FreeGLUT / Linux / C++. Though, Windows, OSX and C compatability are nice bonuses.


That's exactly what I was hinting at, but I was mistaken about there being only two more changes required. There's one more thing to do.

I was a bit thrown off by your use of strcat and strcpy. Those are typically only used when you aren't also storing the length of the string. If you do know the length, you can use memcpy. I wouldn't bother changing them for this assignment, but just so you know.

As for why it's crashing. I'm not sure exactly what your problem is, but I have a suspicion. Your code right there works fine in a simple program with a single append. However, until you address the last issue, multiple appends to the same string are going to result in a buffer-overflow.

Hint: your mistake relates to len.

OpenAL is probably solution you want to use. You could also look into Chipmunk or FMOD.
 

Quasar

Member
Well first of all I would clean up that query because it seems unnecessarily messy. Why are you using a join in the where clause but not the from? Why are you using a right join?

I would do something like
Code:
select distinct 
	Patient.patientID
	,Patient.patientFirstName
	,Patient.patientLastName 
from 
	Patient
join 
	Admission on Patient.patientID = Admission.admissionPatient
where 
	Patient.patientID not in (
		select
			Admission.admissionPatient
		from
			Admission
		join
			Operation on Admission.admissionID = Operation.operationAdmission
		)

I couldn't tell from the context whether the first join was actually necessary. If a patient only appears in the patient table once there's an admission record, I would think it's not.

Right.

Taking your advice to clean it up I came up with the same thing as looking at that I found some errors in my original query, such as it not returning Patients who don't have Admissions, which as it stands it should return (so the first join I used a left outer rather than just a join).


Thanks. I've scoured pages like that, but so far I've not made a lot of progress.

I have this:

Code:
                    var query = (from pat in db.Patients
                                 join ad in db.Admissions on pat.patientID equals ad.admissionPatient
                                 join sub in
                                     (from ad in db.Admissions join op in db.Operations on ad.admissionID equals op.operationAdmission select new { ad.admissionPatient }) on pat.patientID equals sub.admissionPatient
 
                                 select new { pat.patientID, pat.patientFirstName, pat.patientLastName })
                                 .GroupBy(g => new { g.patientID, g.patientFirstName, g.patientLastName})
                                .Select(s => s.FirstOrDefault());

Which does not have the NOT IN implemented and I'm not quite sure how to do it.
 

jokkir

Member
Am I wrong thinking here? My C++ is a bit rusty.

If you add two objects together of the same class eg:

Code:
MyClass c1("This is ");
MyClass c2("a string");
MyClass c3;

c3 = c1 + c2;

I thought it would just append the two strings together without overloading the operator+?

But yeah, I'm a bit rusty so I could be mistaken but I thought you could do this but it was bad implementation.
 

tokkun

Member
Am I wrong thinking here? My C++ is a bit rusty.

If you add two objects together of the same class eg:

Code:
MyClass c1("This is ");
MyClass c2("a string");
MyClass c3;

c3 = c1 + c2;

I thought it would just append the two strings together without overloading the operator+?

But yeah, I'm a bit rusty so I could be mistaken but I thought you could do this but it was bad implementation.

You can append strings with the + operator because it is overloaded in the string class.

If you want + to work with your own custom class, you have to overload it yourself. Just think about it: how is the compiler supposed to know what you want to do when adding two instances of MyClass? How are those strings even related to MyClass? All we can see is that they are passed in the constructor. What if the constructor took 2 string arguments - what would you expect it to append then?
 
Which does not have the NOT IN implemented and I'm not quite sure how to do it.

I had meant to respond to this earlier, but it's pretty annoying to respond to this thread on your phone...

Anyway, your new Lync to SQL query looks much better. The first one would have caused multiple trips to the database and then executing the actual query in memory in the app.

I'm assuming your db.Pats / db.Admissions calls return IQueryable objects. If that's the case, I'd do something like:

Code:
var excludedItems = (from ad in db.Admissions
					 join op in db.Operations on ad.admissionID equals Operation.operationAdmission
					 select ad.admissionPatient);

var query = (from pat in db.Patients
             join ad in db.Admissions on pat.patientID equals ad.admissionPatient
             join sub in
                 (from ad in db.Admissions join op in db.Operations on ad.admissionID equals op.operationAdmission select new { ad.admissionPatient }) on pat.patientID equals sub.admissionPatient
				 where !excludedItems.Contains(pat.patientID)
             select new { pat.patientID, pat.patientFirstName, pat.patientLastName })
             .GroupBy(g => new { g.patientID, g.patientFirstName, g.patientLastName})
             .Select(s => s.FirstOrDefault());

The Select call at the very end is suspect, as I think you could just call .FirstOrDefault() and skip the select, but maybe not depending on the (grouped) anonymous type. Either way, by ensuring that you're using all IQueryables, you delay execution until something in your code tries to return a result (in your case here, the call to FirstOrDefault). This way, all of your stuff will be thrown at the database server and executed there with one result set.

[Edit] I think I'm missing something... Are you just trying to replicate the SQL from above?

If so you can nix the GroupBy call and the FirstOrDefault() entirely and use a Distinct() after the selection of the anonymous type. You could probably also get rid of the joins entirely in the linq...
 

jokkir

Member
You can append strings with the + operator because it is overloaded in the string class.

If you want + to work with your own custom class, you have to overload it yourself. Just think about it: how is the compiler supposed to know what you want to do when adding two instances of MyClass? How are those strings even related to MyClass? All we can see is that they are passed in the constructor. What if the constructor took 2 string arguments - what would you expect it to append then?

How I was thinking it was it would add things together since they're both sharing the same member variables. So if you add both c1 and c2, it would add whatever was inside (so any int would be added to int and any strings would be appended into strings). And since they both have common variables, there would be less problems with it... right?

I know that overloading operators for custom classes is a must but would what I'm saying work? Actually, I think I'll try it myself. I need to review my C++ since it's been over a year since I touched it ~_~
 

Zoe

Member
Right.

Taking your advice to clean it up I came up with the same thing as looking at that I found some errors in my original query, such as it not returning Patients who don't have Admissions, which as it stands it should return (so the first join I used a left outer rather than just a join).

If you want all patients regardless if they have admissions or not, then I don't believe any kind of join to Admissions is necessary in the main query.

Anyway, I dodged the Linq because I really don't bother using that stuff (I do everything through sprocs), but going off the method on StackOverflow it seems like it would be:

Code:
var query = 
	from p in db.Patients
	where !(from a in db.Admission
		join o in db.Operations on a.admissionID equals o.operationAdmission
		select a.admissionPatient)
		.Contains(p.patientId)
	select p;
 

Holden

Member
talking about c :

Is there a function that does like fgets but doesn't stop at newline (\n)

or other alternate solution?

I need to put a full text file ( that includes newlines) to a char*
 

tuffy

Member
talking about c :

Is there a function that does like fgets but doesn't stop at newline (\n)

or other alternate solution?

I need to put a full text file ( that includes newlines) to a char*
You're probably looking for fread which reads chunks of data from a file handle to a buffer, like:
Code:
bytes_read = fread(my_buffer, 1, buffer_size, file_pointer);
 

tokkun

Member
How I was thinking it was it would add things together since they're both sharing the same member variables. So if you add both c1 and c2, it would add whatever was inside (so any int would be added to int and any strings would be appended into strings). And since they both have common variables, there would be less problems with it... right?

I know that overloading operators for custom classes is a must but would what I'm saying work? Actually, I think I'll try it myself. I need to review my C++ since it's been over a year since I touched it ~_~

C++ does not recursively apply operators to members of a class. If you want that to happen, you have to do it manually by implementing the operator in your class.
 

Anustart

Member
I'm writing a program to simulate a parking garage in c++. The professor asks for different probabilities depending on time of day. And wants the distribution to be uniform. If my understanding is correct, I cannot use rand() for this as it isn't uniform. And looking at the documentation for uniform_real_distribution() has me confused :(

Edit: Actually, it seems uniform_int_distribution() is better for my needs. Still unclear how to utilize it.
 

Anustart

Member
Anyone comment on this?

Code:
int entered = 0;
	
	uniform_int_distribution<int> dist(0,longest);
	
	for (int i = 0; i < 21600; i++)
	{
		int entrance = i + dist(generator);
		i = entrance;
		entered++;
	}

longest = 500.

Will this code generate uniform distribution where the next entrance is between 0 and 500 seconds after the last one?
 

Atruvius

Member
I'm creating a little Visual Studio Forms program and I have a little issue.

What is the best way to check when two comboBoxes are not null so a button gets enabled? VS Forms doesn't have any kind of Update function like Unity3D has that would get called every frame?

Haven't used VS forms in over a year so things are a little hazy.
 
I'm creating a little Visual Studio Forms program and I have a little issue.

What is the best way to check when two comboBoxes are not null so a button gets enabled? VS Forms doesn't have any kind of Update function like Unity3D has that would get called every frame?

Haven't used VS forms in over a year so things are a little hazy.

There should be an event that fires when the user selects something from the ComboBox. I believe it's SelectIndexChanged. Create one of those for both ComboBoxes and then check in the event method if the other one has something selected as well. If yes, enable the button. This doesn't scale super well for more than two ComboBoxes, but for two it should be fine.
 

Atruvius

Member
There should be an event that fires when the user selects something from the ComboBox. I believe it's SelectIndexChanged. Create one of those for both ComboBoxes and then check in the event method if the other one has something selected as well. If yes, enable the button. This doesn't scale super well for more than two ComboBoxes, but for two it should be fine.

Ok, I'll do it that way. Cheers!
 
Anyone comment on this?

Code:
int entered = 0;
	
	uniform_int_distribution<int> dist(0,longest);
	
	for (int i = 0; i < 21600; i++)
	{
		int entrance = i + dist(generator);
		i = entrance;
		entered++;
	}

longest = 500.

Will this code generate uniform distribution where the next entrance is between 0 and 500 seconds after the last one?

I don't really understand what this code is trying to do, especially the stuff inside the loop. What exactly do you want to do?
 

maeh2k

Member
Anyone comment on this?

Code:
int entered = 0;
	
	uniform_int_distribution<int> dist(0,longest);
	
	for (int i = 0; i < 21600; i++)
	{
		int entrance = i + dist(generator);
		i = entrance;
		entered++;
	}

longest = 500.

Will this code generate uniform distribution where the next entrance is between 0 and 500 seconds after the last one?

Pretty much, but not quite.
You are using a for loop where i is incremented after every pass. So it look like the entries would be between 1 and 501 seconds after the last ones.
A for loop seems somewhat out of place here, since you manipulate the i inside the loop and the i++ hardly matters at all. Go with a while(i < 21600).
Your local variable doesn't really make it any clearer. Might as well write i += dist(generator). Or better yet i += timeToNextEntry.
 
Top Bottom