Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2

Author Topic: Pathetic Attempts at Programming(A month of learning self-challenge)  (Read 2759 times)

Dakorma

  • Bay Watcher
    • View Profile

So, I've come here, because I want to learn programming, I want to learn it bad. And in that regard, I've decided to forgo the usual amount of video games I play and fanfiction I read for around a month maybe more(Cutting it down to a chapter a day if something updates, and maybe 2 hours a day of video gaming). And focus hard into reading about and doing the actual act of programming. In that regard, I've designed a list of tasks that don’t seem too hard. And will also teach me a lot about the language in question I’m going to be using, C++. These should take me from basic to moderately within the intermediate spheres of programming. I know a bit about the theory of programming, but not a lot about actually implementing that theory. That's what I'd like to learn in this month.

A little breakdown about me, I’m a 22 year old, who last time they attempted college, had a mental breakdown because of social anxiety. Because of my own mental issues(High-functioning Autism, brain damage from suffocation as an infant, and bipolar, as well as Social anxiety and panic disorder), I’m mostly self-taught in just about everything I do. From writing things like this, to programming, to cooking. It leads to a lot mistakes, but in correcting them I try to commit to memory where I went wrong AND where I went right. And maybe I’ll make that mistake 2 or 3 more times(OR less than that if I accidentally set something on fire/broke something beyond repair.) But after that I rarely make that mistake again. I very much believe in the precepts of if you aren’t laughing you aren’t living, and if you aren’t learning you aren’t thinking.

Here’s where you come in, and why I am posting to this esteemed forum. I need your help. I have come up with a bunch of projects, but they’ll probably last me about a week at most. I need more help coming up with things that fit within the basic to intermediate spheres of programming.

I chose C++ because it is THE general purpose language used by the majority of programmers in the applications and games field. While Java comes close, it also has features I dislike. C# is also similarly awkward for me to rationalize.

These projects will be worked on in arbitrary orders. And will use for the early ones at least, base C++11, and the STL.
Without further ado, here is the list of projects I’ll be working on this month. They are open to change so please suggest any that you would think fitting.



Project List 1. The basics of the basics.
Syntax;

Numbers:

Adding, subtracting, dividing and multiplying 2 set numbers.

Adding, subtracting, dividing, and multiplying 2 inputted numbers.

Doing powers between 2 and 10.(Bonus, calculating primes by -1 and using a simple prime check)

Fibonacci sequences up to 100 numbers. ( Bonus, to arbitrary ranges between 1 and 100.)

Writing a functional and mostly accurate calculator.

Strings and Characters:

Printing a string.

Taking and printing back a custom string.

Upcasing and downcasing strings.

Splitting a string at an arbitrarily defined point.

Splitting a string at a defined character.

Manipulating and formatting strings to make block paragraphs of even lengths concatenating the split words with dashs.

Splitting and mixing strings using a push pop array to form a cipher. (Bonus: Using a similar push pop arrangement to make a wacky Engrish generator.)

Class Design:

Implement previous efforts into a proper class structure with the methods, variables and such defined into a header. And implementations in the cpp file.

Project List 2: Puzzles, and design structures.

Make a program to solve the cipher made in the Strings section.

Using Gang of Four design patterns (Command, Singleton, State Machines, Flyweight, Observer, etc, etc) to implement the previous projects. To learn why sometimes OO style programming is Overkill.

The following are suggested by Denzi, who I can't be bothered to look up a user account for here, and whom I talk to on skype quite frequently.
Implement a simulated Need Greed Pass system for an MMO.

Make a creepypasta generator, even if it's just a sentence of creep.

 The above were suggested by Denzi, who I can't be bothered to look up a user account for here, and whom I talk to on skype quite frequently.

Implement previous projects together into a single file.

Well I've written 600 words so far. So I think I’ll wrap this up here.

TL:dr I am going to be programming for a month straight every day, trying to learn as much as possible, but needs help with coming up with simple assignments. Suggestions are welcome, on completion of the month I will reformat and title the post to something like, “Here’s what I learned, and here’s some beginner projects anyone can complete.” and throughout the month my source code will be released, probably daily. I sleep awkward hours though, so expect random times of the day for postings.
« Last Edit: February 27, 2015, 01:16:30 am by Dakorma »
Logged

Urist McScoopbeard

  • Bay Watcher
  • Damnit Scoopz!
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #1 on: February 25, 2015, 09:42:28 pm »

Good luck, and god speed to you sailor. Incredibly admirable, PTW.
Logged
This conversation is getting disturbing fast, disturbingly erotic.

Dakorma

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #2 on: February 26, 2015, 12:02:18 am »

Code: [Select]
#include <iostream>


void adding(int a, int b){
int c;
c = a + b;
std::cout << c << std::endl;
}

void dividing(int a, int b) {
int c;
c = a / b;
std::cout << c << std::endl;
}

void multiplying(int a, int b) {
int c;
c = a * b;
std::cout << c << std::endl;
}

void Input() {
int input1 = 0;
char input2 = ' ';
int input3 = 0;

std::cout << "Enter a basic maths problem.\n";
std::cin >> input1;
std::cin >> input2;
std::cin >> input3;

switch (input2) {
case '*':
multiplying(input1, input3);
break;
case '/':
dividing(input1, input3);
break;
case '-':
adding((input1 + 1), ~input3);
break;
case '+':
adding(input1, input3);
break;
default:
std::cout << "I don't understand\n";
}
}

int main() {
Input();
system("pause");
return 0;
}

Here is adding subtracting, multiplying and dividing. Problems: It can't really do very big numbers well. It only works on pairs of numbers, not multiple numbers. However, purely basic it works. The system("pause") is there to put the program into pause before it returns 0 and thus closes. System calls are relatively awkward, and generally fairly slow. But they work, and in the research I did today on making a program stop before closing after it's complete, are the only 1 line option for this. The other options being code I don't understand, and thus don't want to use because I can't explain them.

Take careful note here.
Code: [Select]
case '-':
adding((input1 + 1), ~input3);
break;
What I'm doing here, is taking the second input and using its 1s complement(Basically taking the bits and flipping the 0s to 1s and the 1s to 0s) to implement subtraction through adding negative numbers. I thought of this, because subtraction is basically the same as addition. More so even than division is like multiplication. As a side effect, because of how 1s complement works presumably, I have to add 1 to the first side otherwise it takes one too many off. Cause I think maybe it forgets about 0. I'm not sure. My next challenge is figuring out why the bitwise not(what converting a number to it's 1s complement is called) is doing this. So I'm going to test it with a small function that prints the numbers 1-100 followed by their 1s complement. Edit soon to follow. This is something relatively easy to implement.

Code: [Select]
#include <iostream>

void onesComp() {
for (int i = 0; i < 100; i++) {
std::cout << "I" << i << " ";
std::cout << "C" << ~i << " ";
}
}

void onesCompPOne() {
for (int i = 0; i < 100; i++) {
std::cout << "I" << (i+1) << " ";
std::cout << "C" << ~i << " ";
}
}

int main() {
onesComp();
std::cout << "Ones Comp + 1\n";
onesCompPOne();
system("pause");
return 0;
}

So here's what I found out, in my researching this topic, 1s complement and 2s complement, are two ways of flipping binary bits. 1's complement results in a drift of 1, where a 2s complement is more accurate. However for our purposes, we can crudely workaround 2s complement by simply removing the drift. It likely does have some inaccuracies somewhere that I'm not aware of though. I'm not sure.
« Last Edit: February 26, 2015, 12:29:12 am by Dakorma »
Logged

bahihs

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #3 on: February 26, 2015, 06:45:30 pm »

I'm no expert on C++, but from those who are, this book is considered to be a very good introduction to C++, taking the reader from beginner to intermediate rather quickly.

Actually the book fits your situation pretty well (its written for those comfortable with a faster pace of learning, who know some level of programming or programming theory already and who want to gain intermediate competence in specifically C++).

However, it starts with stings rather than numbers so you might have to adjust your schedule to fit. But it does have a nice list of exercises at the end of each chapter which are very good at elucidating the ideas laid forth in the chapter.
Logged

Dakorma

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #4 on: February 26, 2015, 09:13:23 pm »

I'm no expert on C++, but from those who are, this book is considered to be a very good introduction to C++, taking the reader from beginner to intermediate rather quickly.

Actually the book fits your situation pretty well (its written for those comfortable with a faster pace of learning, who know some level of programming or programming theory already and who want to gain intermediate competence in specifically C++).

However, it starts with stings rather than numbers so you might have to adjust your schedule to fit. But it does have a nice list of exercises at the end of each chapter which are very good at elucidating the ideas laid forth in the chapter.

Unfortunately that PDF is incredibly badly formatted, I have actually read that book in the past though. That was when I first learned about programming however, and didn't understand much of it, because I was like 10 at the time.

I'm actually working off of my own knowledge+google right now, I've been reading Programming Principles and Practices by Bjarne Stroustrup as well as C++ Primer by a whole lot of people. But I'm also looking at getting a copy of Effective C++ and Effective STL. This is mostly just me relearning programming after a long, long break. Last I really programmed I was like 14. Since then it's mostly been pathetic halfassed attempts at learning, without any real dedication. This time I'm basically setting a regimen and behaving as if it's my job. Fridays and Saturdays are my break days, but I still did some programming on my own. I got the Fibonacci Sequence hammered out yesterday, it looks a bit like this,

Code: [Select]
void fibs(int length) {
int i = 0;
unsigned long fib1 = 1;
unsigned long fib2 = 0;
unsigned long fibs = 0;

while (i < length) {
fib2 = fibs;
fibs = fib1 + fib2;
std::cout << "Fib # " << i + 1 << ". " << fibs << std::endl;

fib1 = fib2;
i++;

}
}
I don't normally like using while loops, but that's just personal preference and my views of them as being fiddly. But I managed to do it with a while loop, where a for loop logic failed me. I could probably do it with a for loop now that I understand the logic behind the Fibonacci Sequence. But the while loop is a bit more elegant, in that I can use the counting to actually print out where in the sequence we are.

Next comes the bonus for this one, I really had to scratch my brain for this one, mostly because I was tired. But I managed to get it, and have it selecting the proper ranges I think. This code is really weird, I know it works, I think I know why it works. And I think that I can explain it half decently, but I can't point out exactly why it works with certainty. Because I don't seem to understand why none of the other solutions I tried gave as many problems as they did.
Code: [Select]
void fibRange(unsigned long rangeStart, unsigned long rangeEnd){
std::vector < unsigned long > range(rangeEnd);

unsigned int i = 0;
unsigned long fib1 = 1;
unsigned long fib2 = 0;
unsigned long fibs = 0;

while (i < rangeEnd) {
fib2 = fibs;
fibs = fib1 + fib2;
fib1 = fib2;
range.push_back(fibs);

i++;
}

range.erase(range.begin(), range.begin() + rangeStart);
range.erase(std::remove(range.begin(), range.end(), 0), range.end());


for (std::vector<unsigned long>::iterator i = range.begin() + rangeStart; i != range.end(); ++i)
std::cout << *i << ' ';
}
So what this does, is run a while loop that is functionally very similar to the while loop for the Fibonacci calculator above, and stores at the back of a vector(Which are basically dynamic sized arrays in C++) each number in turn. For some reason this was giving a lot of inconsistent results when I tried to display it there at the bottom. I tried not deleting the contents and pointing the iterator at the beginning of the vector + the rangeStart variable. But that resulted in it printing everything no matter what I did. I tried range.erasing only the contents that were unnecessary but that resulted in it spitting a bunch of zeroes at me, and then spitting the sequence in full at me. I then tried deleting only the contents that were unnecessary, and then displaying from the range start, and that got it printing a fuck tonne of zeroes at me, and then printing the right sequence. Then I basically stumbled in my googling on the erase/remove structure, and used it to remove all the zeros and for some reason it works now. I think. As far as I know.


I learned a bit about vectors as well, and what you can and can't do with them. Because in the process of figuring out how to implement all of these solutions I made a metric fucktonne of mistakes, that allowed me to learn things that I probably wouldn't have otherwise. Like I was trying to erase with a for loop at one point, but that for loops was iterating based on rangeStart, and that caused it to count past the edge of the vector, resulting in a scary error that took me like 20 mins to figure out, and realize that I shouldn't even be using a for loop, given that I can erase in a range anyway. I also learned that I over-zealously use loops even when I shouldn't. So I need to curb that, and think about when and if I should be using what I'm using.

As a side note, given that my last attempt at programming was using Java, I initially tried using an Array to store the sequence, but that method doesn't work in C++ because without garbage collection you can't really have dynamically sized arrays. Even the Vector I used there is very memory inefficient and is not something you want to use in high speed, high efficiency production code, like a video game, it's faster memory wise, to just define an arbitrary length for an array(or use a custom struct, IIRC), then to use something like a Vector that resizes and moves itself automatically in memory.  However with that you run the risk of defining either overly much memory, and causing inefficiency there, or defining more values than the array can store, and thus creating a memory leak or bug when you try and access those out of memory entities. It's really a careful balance, and code can benefit both from the simplicity of vectors, and from the speed of simple arrays. Ideally you want to keep vectors to non-performance critical code, and arrays, to where you really, really need to both, know what you are doing, and have a lot of speed doing it. I learned this from googling around. Working on the powers of, and prime checker now.  Oh and I also did some interesting stuff with strings that I'll mess with more later and see if I can get it working better. But splitting a string is relatively easy with the STL. It's going to be interesting splitting it at set points though, and inputting the dash.
Logged

cerapa

  • Bay Watcher
  • It wont bite....unless you are the sun.
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #5 on: February 27, 2015, 05:19:23 am »

You seem to be overcomplicating things. Like heavily overcomplicating them.

As far as "for" loops are concerned:
Code: [Select]
while (i < length) {
fib2 = fibs;
fibs = fib1 + fib2;
std::cout << "Fib # " << i + 1 << ". " << fibs << std::endl;

fib1 = fib2;
i++;

}
is equivalent to
Code: [Select]
for (int i = 0; i < length; i++) {
fib2 = fibs;
fibs = fib1 + fib2;
std::cout << "Fib # " << i + 1 << ". " << fibs << std::endl;

fib1 = fib2;
}


And the second thing. You aren't really supposed to delete things in arbitrary places in vectors. It's fast to shave stuff off the end and to add stuff to the end, but doing anything in the middle requires reassigning the entire vector. If you want fast deletions then use lists.

Code: [Select]
void fibRange(unsigned long rangeStart, unsigned long rangeEnd){
std::vector < unsigned long > range(rangeEnd);

unsigned int i = 0;
unsigned long fib1 = 1;
unsigned long fib2 = 0;
unsigned long fibs = 0;

while (i < rangeEnd) {
fib2 = fibs;
fibs = fib1 + fib2;
fib1 = fib2;
range.push_back(fibs);

i++;
}

range.erase(range.begin(), range.begin() + rangeStart);
range.erase(std::remove(range.begin(), range.end(), 0), range.end());


for (std::vector<unsigned long>::iterator i = range.begin() + rangeStart; i != range.end(); ++i)
std::cout << *i << ' ';
}

Is entirely weird. While creating the vector, you do it with "range(rangeEnd);" which creates rangeEnd amount of zeroes in the vector. Which you later delete. There is literally no point to doing this.
You also account for "rangeStart" twice. First by deleting the earlier ones with "range.erase(range.begin(), range.begin() + rangeStart);" and later in the for loop.

And the for loop could just be:
Code: [Select]
for (int i = rangeStart; i < range.size(); ++i)
std::cout << range[i] << ' ';


I would honestly say you have some rather freaky habits. Exceptionally freaky habits, with the way you tried to do subtraction. Just use a goddamn minus sign dude. I see literally zero benefit to your weird method. I feel like you have a sort of strong theoretical base, but little understanding of actual coding practises.
« Last Edit: February 27, 2015, 05:27:50 am by cerapa »
Logged

Tick, tick, tick the time goes by,
tick, tick, tick the clock blows up.

Dakorma

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #6 on: February 27, 2015, 05:55:33 am »

snip

The benefit to the subtraction by addition is not having an additional method loaded in the ram, as well as not having to write said method which would be exactly the same as the other 3 just with one symbol changed. More than that, I knew from the principles of math, that if you can find the negative complement of a number, IE, the "nega-version" as a friend of mine so fondly called it ages ago. You can simply add that to the positive number, to replicate subtraction, by adding a negative number. Essentially, 11 + -11 == 11 - 11. And I just realized I probably completely missed your point, and have to test something real quick. OH GOD DAMN IT.*Deep breaths* I didn't realize you could negative out variables, simply by adding a - in front of them, I thought that was something you had to do on assignment of the variable.
 
As for that for loop I literally found it while searching stackoverflow for the problem I was having, and just copied the methodology there. Thank you for the help on that. I wrote the whole fib range thing after about 18 hours of not sleeping. Going to rewrite the whole method to be cleaner and less weird now that I have had a day with the knowledge sitting, because it is weird, and I admitted it, it was the result of me trying incredibly hard to figure out a problem that you answered for me. For some reason, I thought that range(rangeEnd) would initialize with values of void or null, and allow those void values to be reassigned, not that it would assign those technically empty values to zero. And finally, the delete necessity, was formed because of the 0's that formed from the assignment. Also I hadn't looked up lists at that point, so I didn't know if they were appropriate. I simply came across vectors again, googling something like  "resizable array C++" and browsing stackoverflow. Not making excuses, just explaining the logic I used. I supposed I should take this as a lesson that online sources very rarely can be trusted.

And I wasn't trying to do it fast, I was trying to fix a problem, in a way I could understand, using tools I understood, at least partially. This can lead to some awkwardness, and for that I apologize.

::EDIT::
Here's the new Fibonacci range method.

Code: [Select]
void fibRange(unsigned long rangeStart, unsigned long rangeEnd){
std::vector < unsigned long > range;

unsigned int i = 0;
unsigned long fib1 = 1;
unsigned long fib2 = 0;
unsigned long fibs = 0;

for (int i = 0; i < rangeEnd; i++) {
fib2 = fibs;
fibs = fib1 + fib2;
range.push_back(fibs);

fib1 = fib2;
}

for (int i = rangeStart - 1; i < range.size(); ++i)
std::cout << "Fib # " << i + 1 << ". " << range[i] << std::endl;
}

Much more sane, and not like I was up all night trying to figure out what the fuck was happening because I didn't fully understand vector.

::Minor EDIT to fix derpyness::
« Last Edit: February 27, 2015, 06:12:40 am by Dakorma »
Logged

cerapa

  • Bay Watcher
  • It wont bite....unless you are the sun.
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #7 on: February 27, 2015, 06:15:33 am »

Exactly what things have you been reading, that loading an additional function is even a concern? That's like making a truck go faster by not wearing shoes. The effect is ridicilously small, if there even is one. Besides, I don't particularly understand why you would have the functions in the first place.
Code: [Select]
void adding(int a, int b){
int c;
c = a + b;
std::cout << c << std::endl;
}
can be replaced with just
Code: [Select]
std::cout << a + b << std::endl;
« Last Edit: February 27, 2015, 06:17:05 am by cerapa »
Logged

Tick, tick, tick the time goes by,
tick, tick, tick the clock blows up.

Dakorma

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #8 on: February 27, 2015, 06:43:00 am »

Exactly what things have you been reading, that loading an additional function is even a concern? That's like making a truck go faster by not wearing shoes. The effect is ridicilously small, if there even is one. Besides, I don't particularly understand why you would have the functions in the first place.
Code: [Select]
void adding(int a, int b){
int c;
c = a + b;
std::cout << c << std::endl;
}
can be replaced with just
Code: [Select]
std::cout << a + b << std::endl;
I'm not saying it's an issue. I'm saying that there are advantages to it. Teeny tiny ones, but they exist and they are advantages.

Further, the reason I use the methods and calls to them, is because while I could just have my input method do it all, I felt it looked cleaner to define the methods of how to do math, and then call them. As well as, and I think this is actually what your issue with how I'm doing this is, using an intermediary variable, because, and I find it hard to describe this, it just feels more confusing to write it as you said, because it seems to confuse where the result is coming from. And it allows me to later generalize it to work in a multiple party math problem(1*2*3*4), by simply taking each number in turn, feeding it into multiplication, and taking a return c(converting to int multiply) value, and using that as a, and the next number as b. And then using that return value to be a, and the next value to be b. In fact figuring out how to actually do that sounds like a wonderful way to spend my next hour. Thank you for the inspiration

But before I go I'll say this, regarding the issue of not having a subtraction method. It's just an issue of style. If I can write less code I will, even if it confuses others, purely because it doesn't confuse me.
Logged

alexandertnt

  • Bay Watcher
  • (map 'list (lambda (post) (+ post awesome)) posts)
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #9 on: February 27, 2015, 08:57:20 am »

Quote
Further, the reason I use the methods and calls to them, is because while I could just have my input method do it all, I felt it looked cleaner to define the methods of how to do math, and then call them. As well as, and I think this is actually what your issue with how I'm doing this is, using an intermediary variable, because, and I find it hard to describe this, it just feels more confusing to write it as you said, because it seems to confuse where the result is coming from.

I would seriously recommend just using the + - / * symbols. Not only do your functions add unnecessary complexity, they are adding more lines of code, and consuming more (albeit a completely negligible amount of) RAM (which was your reason for not adding the - function in the first place, oddly enough).

It is not confusing where the result is coming from, the whole pattern of creating a variable and assigning to it conditionally is extremely common and very clear.

Quote
And it allows me to later generalize it to work in a multiple party math problem(1*2*3*4), by simply taking each number in turn, feeding it into multiplication, and taking a return c(converting to int multiply) value, and using that as a, and the next number as b.

Your not solving anything. You still have to hard code the number of function calls, as multiply(multiply(multiply(a,b),c),d) can only take exactly 4 values. And looks like ass in comparison to a*b*c*d.

If your trying to apply this principle to an arbitrary number of values, this is what std::accumulate does, using containers.

Your proposing writing functional version of the math operators, which would be useful for std::accumulate, but for such trivial functions, you would be far better off just passing a lambda expression with std::accumulate.

Quote
If I can write less code I will, even if it confuses others, purely because it doesn't confuse me.

You say that now, but when you come back a year later to the library you built, full of adding functions that output to stdout and calls to adding that use logical nots to do subtraction, your going to regret it. On top of that, many things you have done have just added code.

Quote
For some reason, I thought that range(rangeEnd) would initialize with values of void or null, and allow those void values to be reassigned, not that it would assign those technically empty values to zero.

I think what you were trying to do was pre-allocate the memory for the vector, so it didn't have to keep resizing the vector. What you have to do is access the element with the square brackets. if you just use push_back, you will start to add more onto the list without altering those initial values. I also tweaked it so it wouldn't waste RAM by storing numbers that are never used. (it is untested)

Code: [Select]
void fibRange(unsigned long rangeStart, unsigned long rangeEnd){
        // create a vector with enough space to hold all the values we are going to generate
std::vector < unsigned long > range(rangeEnd - rangeStart);

//unsigned int i = 0; // we declare i in the for loops, this is unnecessary
unsigned long fib1 = 1;
unsigned long fib2 = 0;
unsigned long fibs = 0;

for (unsigned int i = 0; i < rangeEnd; i++) {
fib2 = fibs;
fibs = fib1 + fib2;
                // naturally, we only want to store the numbers in the range we are actually interested in
                if (i >= rangeStart)
    range[i-rangeStart] = fibs; // since our array is 0 indexed, we subtract rangeStart from i. We want to add the values we are interested in at the start of the array, otherwise we are just wasting memory on unused space.

fib1 = fib2;
}

     // since range now starts with the first value we are interested in, and ends in the last, just print the array contents starting at 0
for (unsigned int i = 0; i < range.size(); ++i) // why i++ above, but ++i here?
std::cout << "Fib # " << (i + 1 + rangeStart) << ". " << range[i] << std::endl;
}



As for some more general advice:

Your functions should be named after their action. Name them something like "Add" instead of "Adding" or "Multiply" instead of "Multiplying". Your input functions is badly named, it does not clearly define what it does (Input what? Pizza?). On top of that, your "Input" function paradoxically outputs to stdout as an important part of its function.

You need to slow down and lean some more of the basics before you start using things like Vectors. Have you tried doing the fib problem with a good old fashioned array? Save micro-optimisations for later until you have a better idea for the actual impact of things like a function declaration, and a better understanding of how code works in general.
Logged
This is when I imagine the hilarity which may happen if certain things are glichy. Such as targeting your own body parts to eat.

You eat your own head
YOU HAVE BEEN STRUCK DOWN!

cerapa

  • Bay Watcher
  • It wont bite....unless you are the sun.
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #10 on: February 27, 2015, 09:53:18 am »

You don't actually need to do the preallocation of the vector. Vectors naturally keep a buffer for that. You can get the size of the vector+buffer with capacity(). If you're afraid it isn't big enough, then you can use reserve() to set the size.
Logged

Tick, tick, tick the time goes by,
tick, tick, tick the clock blows up.

alexandertnt

  • Bay Watcher
  • (map 'list (lambda (post) (+ post awesome)) posts)
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #11 on: February 27, 2015, 02:19:43 pm »

You don't actually need to do the preallocation of the vector. Vectors naturally keep a buffer for that. You can get the size of the vector+buffer with capacity(). If you're afraid it isn't big enough, then you can use reserve() to set the size.

Oh yeah, that. Probably makes more sense to use reserved and push_back then.
« Last Edit: February 27, 2015, 02:25:31 pm by alexandertnt »
Logged
This is when I imagine the hilarity which may happen if certain things are glichy. Such as targeting your own body parts to eat.

You eat your own head
YOU HAVE BEEN STRUCK DOWN!

Dakorma

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #12 on: February 27, 2015, 06:18:45 pm »

Quote
Further, the reason I use the methods and calls to them, is because while I could just have my input method do it all, I felt it looked cleaner to define the methods of how to do math, and then call them. As well as, and I think this is actually what your issue with how I'm doing this is, using an intermediary variable, because, and I find it hard to describe this, it just feels more confusing to write it as you said, because it seems to confuse where the result is coming from.

I would seriously recommend just using the + - / * symbols. Not only do your functions add unnecessary complexity, they are adding more lines of code, and consuming more (albeit a completely negligible amount of) RAM (which was your reason for not adding the - function in the first place, oddly enough).

It is not confusing where the result is coming from, the whole pattern of creating a variable and assigning to it conditionally is extremely common and very clear.

Quote
And it allows me to later generalize it to work in a multiple party math problem(1*2*3*4), by simply taking each number in turn, feeding it into multiplication, and taking a return c(converting to int multiply) value, and using that as a, and the next number as b.

Your not solving anything. You still have to hard code the number of function calls, as multiply(multiply(multiply(a,b),c),d) can only take exactly 4 values. And looks like ass in comparison to a*b*c*d.

If your trying to apply this principle to an arbitrary number of values, this is what std::accumulate does, using containers.

Your proposing writing functional version of the math operators, which would be useful for std::accumulate, but for such trivial functions, you would be far better off just passing a lambda expression with std::accumulate.

Quote
If I can write less code I will, even if it confuses others, purely because it doesn't confuse me.

You say that now, but when you come back a year later to the library you built, full of adding functions that output to stdout and calls to adding that use logical nots to do subtraction, your going to regret it. On top of that, many things you have done have just added code.

Quote
For some reason, I thought that range(rangeEnd) would initialize with values of void or null, and allow those void values to be reassigned, not that it would assign those technically empty values to zero.

I think what you were trying to do was pre-allocate the memory for the vector, so it didn't have to keep resizing the vector. What you have to do is access the element with the square brackets. if you just use push_back, you will start to add more onto the list without altering those initial values. I also tweaked it so it wouldn't waste RAM by storing numbers that are never used. (it is untested)

Code: [Select]
void fibRange(unsigned long rangeStart, unsigned long rangeEnd){
        // create a vector with enough space to hold all the values we are going to generate
std::vector < unsigned long > range(rangeEnd - rangeStart);

//unsigned int i = 0; // we declare i in the for loops, this is unnecessary
unsigned long fib1 = 1;
unsigned long fib2 = 0;
unsigned long fibs = 0;

for (unsigned int i = 0; i < rangeEnd; i++) {
fib2 = fibs;
fibs = fib1 + fib2;
                // naturally, we only want to store the numbers in the range we are actually interested in
                if (i >= rangeStart)
    range[i-rangeStart] = fibs; // since our array is 0 indexed, we subtract rangeStart from i. We want to add the values we are interested in at the start of the array, otherwise we are just wasting memory on unused space.

fib1 = fib2;
}

     // since range now starts with the first value we are interested in, and ends in the last, just print the array contents starting at 0
for (unsigned int i = 0; i < range.size(); ++i) // why i++ above, but ++i here?
std::cout << "Fib # " << (i + 1 + rangeStart) << ". " << range[i] << std::endl;
}



As for some more general advice:

Your functions should be named after their action. Name them something like "Add" instead of "Adding" or "Multiply" instead of "Multiplying". Your input functions is badly named, it does not clearly define what it does (Input what? Pizza?). On top of that, your "Input" function paradoxically outputs to stdout as an important part of its function.

You need to slow down and lean some more of the basics before you start using things like Vectors. Have you tried doing the fib problem with a good old fashioned array? Save micro-optimisations for later until you have a better idea for the actual impact of things like a function declaration, and a better understanding of how code works in general.
Thank you for your advice. I am incredibly inconsistent in how I write code, and I apologize for that. I am however, a newbie, and am trying to get used to all of this. Most of what I know is theory, not practice, and I need to remember that. And as far as fibRange with just an array, no I considered using an array, but vectors seemed like a much better choice at the time. I probably would have saved myself hours of fiddling just defining an array of 100 unsigned longs, however the code itself as awkward as it was, and likely still is, works for any value now, not just values of less than 100. Though it would likely overflow the unsigned long if you went over 100. I've never argued that I'm doing it the correct way, I've merely been explaining my reasons behind doing what I did. Even explaining when those reasons are personal preference.
Logged

Dakorma

  • Bay Watcher
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #13 on: March 05, 2015, 06:03:24 am »

So I decided to start over. Scrap everything, because apparently I've done it all wrong according to the above 2 posters. I'm going to be working out of a book, called C++ Primer 5th Edition, I'm still going to treat this like a job, but it will be more lesson oriented. I'll be honest, being told, a lot of the stuff you guys told me, discouraged me for a few days. Contemplated giving it up entirely, contemplated a lot of things. But I'm not going to let depression win. As such, I've started going through the C++ Primer 5th Edition, which covers things like C++11, and is a bit slower than Accelerated C++ is. It also clocks in at a massive 1000+ pages. I'm skipping posting a few things, because well, some of the things are boring for you guys. But I will do them, however updates will be a bit slower.

Alright so first question to the programmers out there, C++ Primer has this to say about std::cout,
"The <<operator takes two operands: The left-hand operand must be an ostream
object; the right-hand operand is a value to print. The operator writes the given value
on the given ostream. The result of the output operator is its left-hand operand.
That is, the result is the ostream on which we wrote the given value.
Ouroutput statement uses the <<operator twice. Because the operator returns its
left-hand operand, the result of the first operator becomes the left-hand operand of
the second. As a result, we can chain together output requests."

It then goes onto say, that

std::cout << "Enter 2 numbers: " << std::endl;

is equivalent to

(std::cout << "Enter 2 numbers: ") << std::endl;

Does that mean, when you cout something, and you are chaining things together with << operators, each link in the chain, is basically including all of the previous ones because the operator is returning everything to the left of it? If so, would it be smarter/more efficient for the compiler to write it out as

std::cout << "Enter 2 numbers: ";
std::cout << std::endl;

or even

std::cout << "Enter 2 numbers: \n"

This is just a curiosity. Not something I'm planning on incorporating, literally just a random fit of interest in how it works, but a lack of ability to test it. Though, later on the same page it mentions something about how endl flushes the buffer, and that it's best to flush the buffer, so that if a program crashes it doesn't leave bits hanging around in memory. Hrm, is \n equivalent to an endl, I doubt it. This is rather interesting. A little googling suggested that the third one is more efficient because of how long it takes flush the buffer. So in cases of messing around with pure text, and needing highly performent code, you'd not use std::endl. Because it is the largest reason why C++ IO is generally slower than that of C.

But in regards to the first few exercises, I like that they don't show you hello world, but leave you to infer how to make hello world from a slightly more advanced bit of code.

The code in 1.6 is fine barring the semicolon placement, removing the semicolons makes it print correctly. Alternatively and this is possibly the answer they are looking for, adding std::cout in front of each line would make it work. Here's the code in question they wanted you to state if it would work, what it was supposed to do and how to fix it if it didn't.
Code: [Select]
std::cout<< "The sum of "  << v1;
<< " and " << v2;
<< " is " << v1 + v2 << std::endl;

1.7 is just inputting and viewing an error for nested comments, that error looked like this,
Code: [Select]
1>d:\users\tyler\documents\visual studio 2013\projects\c++primer5th\chapter1\comments.cpp(1): warning C4138: '*/' found outside of comment
1>d:\users\tyler\documents\visual studio 2013\projects\c++primer5th\chapter1\comments.cpp(1): error C2059: syntax error : '/'

1.8 is a bit more interesting,
Code: [Select]
Exercise 1.8: Indicate which, if any, of the following output statements are
legal:

std::cout << "/*";
std::cout << "*/";
std::cout << /* "*/" */;
std::cout << /*  "*/" /* "/*"  */;
After you’ve predicted what will happen, test your answers by compiling a
program with each of these statements. Correct any errors you encounter.
I think the first and second ones are the only ones that work. The first one is the definite might, which the second will definitely work. 

The fourth ones possibly working. Let's actually figure that out, following along, open comment, close comment, within quotation marks,  one quotation mark visible to the program, open comment, invisible because it is within quotations, followed by an open comment within quotation. Will work I think, because it closes the quotes then begins the next set of comments.  But very tricky and maybe wrong.

The third definitely won't work, because it's calling cout without closing the output's quotes.

Time to check if those actually were right answers.

First and second worked, third tossed these errors,
Code: [Select]
1>d:\users\tyler\documents\visual studio 2013\projects\c++primer5th\chapter1\comments.cpp(10): error C2001: newline in constant
1>d:\users\tyler\documents\visual studio 2013\projects\c++primer5th\chapter1\comments.cpp(12): error C2143: syntax error : missing ';' before 'return'

The fourth amazingly works, I was really guessing hard on that one. But I guess I should have guessed easier because of how the first one passed. On to chapter 1.4.
Logged

cerapa

  • Bay Watcher
  • It wont bite....unless you are the sun.
    • View Profile
Re: Pathetic Attempts at Programming(A month of learning self-challenge)
« Reply #14 on: March 05, 2015, 07:11:02 am »

You hadn't done it all wrong, you had just done it in odd ways. And quite frankly that's not always a bad thing. I'm pretty sure you could come up with way better solutions to some problems than I could. Plus I'm honestly way more confused by my own older code than your current code. Keep at it, and you'll be fine.

Also, try to have some fun in the process instead of treating it like a job. Personally I learned by skimming through this tutorial(try it out, it's a lot shorter than your book, and you can already skip the 1st chapter), and going off to do whatever, and pulling up the tutorial again when I had a problem I thought I could solve with something I didn't yet understand. Kinda puts everything into perspective when you see what kinds of problems they can solve. Also, it shows you what kinds of things aren't important and what are. I have a bit of a streak for unneeded optimization, so actually trying to get something to work instead of just optimizing disparate parts curbs that instinct.


Anyway, as for your questions:

std::cout << "A" << std::endl;
is equivalent to
std::cout << "A";
std::cout << std::endl;

<< doesn't make a copy of the ostream, but rather returns a reference to it. Think of the stream as a piece of paper that is written on by <<. Instead of making a copy each time it's called in sequence, it instead passes the piece of paper along to the right.


I did some testing on using "/n" and you are kinda correct.

std::cout << "Enter 2 numbers: " << std::endl;
takes 40% more time than
std::cout << "Enter 2 numbers: \n";

But it doesn't seem to have anything to do with clearing buffers.
std::cout << "Enter 2 numbers:" << "\n";
Takes nearly the same amount of time as
std::cout << "Enter 2 numbers: " << std::endl;

So at fault is the additional call to <<.

I don't see much value in using this level of optimization, but it might speed up writing to files to some degree.
Logged

Tick, tick, tick the time goes by,
tick, tick, tick the clock blows up.
Pages: [1] 2