• 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

Nobody in my life understands how great it feels to finally find a solution to a problem. I finally got a lightbox element to work correctly and it feels like victory to me.
Yeah, there's a very Sherlock Holmesian quality to it. Thrill of the hunt kind of thing...

And people think programming is boring! Hell no.

Frustrating? Hell yes

And 100% test coverage.
:lol

I don't know why this got me.
 
Fuck it. I can't figure out what is wrong. I'm trying to make a game like scrabble/text twist. This is from the MIT intro computer science lectures. I'll post the problem and then the code.

I'm currently testing it bit by bit. So far it works as intended, except lets say my letter selection is "b, b, a, l, e, v, c, l"

If the user inputs "ball" as their word, it will then update the hand and give: "e, v, c"

For some reason it erases BOTH b's from the hand despite the user only using one of their two b's to make the word ball. Now perhaps it is subtracting one more than needed for each letter. But if that is the case I should get an error message when it checks to see if I even have enough of a particular letter in hand to make a word.

Code:
# 6.00 Problem Set 3A Solutions
#
# The 6.00 Word Game
# Created by: Kevin Luu <luuk> and Jenna Wiens <jwiens>
#
#

import random
import string

VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 7

SCRABBLE_LETTER_VALUES = {
    'a': 1, 'b': 3, 'c': 3, 'd': 2, 'e': 1, 'f': 4, 'g': 2, 'h': 4, 'i': 1, 'j': 8, 'k': 5, 'l': 1, 'm': 3, 'n': 1, 'o': 1, 'p': 3, 'q': 10, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 4, 'w': 4, 'x': 8, 'y': 4, 'z': 10
}

# -----------------------------------
# Helper code
# (you don't need to understand this helper code)

WORDLIST_FILENAME = "words.txt"

def load_words():
    """
    Returns a list of valid words. Words are strings of lowercase letters.
    
    Depending on the size of the word list, this function may
    take a while to finish.
    """
    print "Loading word list from file..."
    # inFile: file
    inFile = open(WORDLIST_FILENAME, 'r', 0)
    # wordlist: list of strings
    wordlist = []
    for line in inFile:
        wordlist.append(line.strip().lower())
    print "  ", len(wordlist), "words loaded."
    return wordlist

def get_frequency_dict(sequence):
    """
    Returns a dictionary where the keys are elements of the sequence
    and the values are integer counts, for the number of times that
    an element is repeated in the sequence.

    sequence: string or list
    return: dictionary
    """
    # freqs: dictionary (element_type -> int)
    freq = {}
    for x in sequence:
        freq[x] = freq.get(x,0) + 1
    return freq
	

# (end of helper code)
# -----------------------------------

#
# Problem #1: Scoring a word
#
def get_word_score(word, n):
    """
    Returns the score for a word. Assumes the word is a
    valid word.

	The score for a word is the sum of the points for letters
	in the word multiplied by the length of the word, plus 50
	points if all n letters are used on the first go.

	Letters are scored as in Scrabble; A is worth 1, B is
	worth 3, C is worth 3, D is worth 2, E is worth 1, and so on.

    word: string (lowercase letters)
    returns: int >= 0
    """
    score = 0 
    for i in word:
        score = score + SCRABBLE_LETTER_VALUES[i] 
	
    if len(word) == n:
        score = score * len(word) + 50 
        return score 
		
    else: 
        score = score * len(word) 
        return score 
    # TO DO...
    
#
# Make sure you understand how this function works and what it does!
#
def display_hand(hand):
    """
    Displays the letters currently in the hand.

    For example:
       display_hand({'a':1, 'x':2, 'l':3, 'e':1})
    Should print out something like:
       a x x l l l e
    The order of the letters is unimportant.

    hand: dictionary (string -> int)
    """
    for letter in hand.keys():
        for j in range(hand[letter]):
             print letter,              # print all on the same line
    print                               # print an empty line

#
# Make sure you understand how this function works and what it does!
#
def deal_hand(n):
    """
    Returns a random hand containing n lowercase letters.
    At least n/3 the letters in the hand should be VOWELS.

    Hands are represented as dictionaries. The keys are
    letters and the values are the number of times the
    particular letter is repeated in that hand.

    n: int >= 0
    returns: dictionary (string -> int)
    """
    hand={}
    num_vowels = n / 3
    
    for i in range(num_vowels):
        x = VOWELS[random.randrange(0,len(VOWELS))]
        hand[x] = hand.get(x, 0) + 1
        
    for i in range(num_vowels, n):    
        x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
        hand[x] = hand.get(x, 0) + 1
        
    return hand

#
# Problem #2: Update a hand by removing letters
#
def update_hand(hand, word):
    """
    Assumes that 'hand' has all the letters in word.
	In other words, this assumes that however many times
	a letter appears in 'word', 'hand' has at least as
	many of that letter in it. 

    Updates the hand: uses up the letters in the given word
    and returns the new hand, without those letters in it.

    Has no side effects: does not modify hand.

    word: string
    hand: dictionary (string -> int)    
    returns: dictionary (string -> int)
    """
    new_hand = hand.copy() 
    for i in word:
        new_hand[i] = new_hand[i] - 1 
    return new_hand 
    # TO DO ...

#
# Problem #3: Test word validity
#
def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.
    
    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
    if word not in word_list:
        return False 
    elif word in word_list:
        for i in word:
            if i not in hand.keys(): 
                return False 
            else:
                hand[i] = hand[i] - 1
                if hand[i] < 0:
                    return False 
    return True 
    # TO DO...

def calculate_handlen(hand):
    handlen = 0
    for v in hand.values():
        handlen += v
    return handlen

#
# Problem #4: Playing a hand
#
def play_hand(hand, word_list):
    print "Welcome to text twist."
    hand = hand.copy()
    while True:
        display_hand(hand)
        input = raw_input("Please input a word." )
        if is_valid_word(input, hand, word_list):
            hand = update_hand(hand, input)
        elif input == ".":
            break 		
    """
    Allows the user to play the given hand, as follows:

    * The hand is displayed.
    
    * The user may input a word.

    * An invalid word is rejected, and a message is displayed asking
      the user to choose another word.

    * When a valid word is entered, it uses up letters from the hand.

    * After every valid word: the score for that word is displayed,
      the remaining letters in the hand are displayed, and the user
      is asked to input another word.

    * The sum of the word scores is displayed when the hand finishes.

    * The hand finishes when there are no more unused letters.
      The user can also finish playing the hand by inputing a single
      period (the string '.') instead of a word.

      hand: dictionary (string -> int)
      word_list: list of lowercase strings
      
    """
    # TO DO ...

#
# Problem #5: Playing a game
# Make sure you understand how this code works!
# 
def play_game(word_list):
    a = deal_hand(7)
    b = play_hand(a, word_list) 
    """
    Allow the user to play an arbitrary number of hands.

    * Asks the user to input 'n' or 'r' or 'e'.

    * If the user inputs 'n', let the user play a new (random) hand.
      When done playing the hand, ask the 'n' or 'e' question again.

    * If the user inputs 'r', let the user play the last hand again.

    * If the user inputs 'e', exit the game.

    * If the user inputs anything else, ask them again.
    """
    # TO DO...

#
# Build data structures used for entire session and play game
#
if __name__ == '__main__':
    word_list = load_words()
    play_game(word_list)
 
Fuck it. I can't figure out what is wrong. I'm trying to make a game like scrabble/text twist. This is from the MIT intro computer science lectures. I'll post the problem and then the code.

I'm currently testing it bit by bit. So far it works as intended, except lets say my letter selection is "b, b, a, l, e, v, c, l"

If the user inputs "ball" as their word, it will then update the hand and give: "e, v, c"

For some reason it erases BOTH b's from the hand despite the user only using one of their two b's to make the word ball. Now perhaps it is subtracting one more than needed for each letter. But if that is the case I should get an error message when it checks to see if I even have enough of a particular letter in hand to make a word.

Alright, first I'd recommend you post the code as a Gist (https://gist.github.com/) or on Pastebin because that's a lot of code for one post. Second, I tried to run your code and it couldn't find the word list (words.txt), so if you post a full program, include everything you need to run it (a Gist can also have more than one file, so that's really useful). From reading some of the code it looks like your issue is probably in the update_hand function.

Have you tried inserting a bunch of print statements everywhere that output the state of the program? In the update_hand method I'd print the state of the new hand after each loop iteration. That seems to be where you're probably losing your letters. Also, you can try "fixing" a test input (make it independent of the random number generator by hardcoding in values like you suggested) and then go over it with a debugger. I don't know much about Python debuggers but from a bit of googling, this seems promising.
 
Alright, first I'd recommend you post the code as a Gist (https://gist.github.com/) or on Pastebin because that's a lot of code for one post. Second, I tried to run your code and it couldn't find the word list (words.txt), so if you post a full program, include everything you need to run it (a Gist can also have more than one file, so that's really useful). From reading some of the code it looks like your issue is probably in the update_hand function.

Have you tried inserting a bunch of print statements everywhere that output the state of the program? In the update_hand method I'd print the state of the new hand after each loop iteration. That seems to be where you're probably losing your letters. Also, you can try "fixing" a test input (make it independent of the random number generator by hardcoding in values like you suggested) and then go over it with a debugger. I don't know much about Python debuggers but from a bit of googling, this seems promising.

Ah sorry. I'll do that later when I get the chance.

But first I'll just insert print statements everywhere and see where the problem is occurring.

edit: The problem lied in how I verified that the word was a valid input.

Code:
def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.
    
    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
    if word not in word_list:
        return False 
    elif word in word_list:
        for i in word:
            if i not in hand.keys(): 
                return False 
            else:
                hand[i] -= 1
                if hand[i] < 0:
                    return False 
    return True

When they input a word, the play_game function calls the verify_word function. Apparently the stuff under else was mutating the hand. I assumed it wouldn't because I wasn't returning the hand, but was just calling the verify function to give me a True or False. The problem seems solved by simply inserting a hand = hand.copy() right under the else, but above the hand -= 1. No clue why though.
 
Ah sorry. I'll do that later when I get the chance.

But first I'll just insert print statements everywhere and see where the problem is occurring.

edit: The problem lied in how I verified that the word was a valid input.

Code:
def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.
    
    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
    if word not in word_list:
        return False 
    elif word in word_list:
        for i in word:
            if i not in hand.keys(): 
                return False 
            else:
                hand[i] -= 1
                if hand[i] < 0:
                    return False 
    return True

When they input a word, the play_game function calls the verify_word function. Apparently the stuff under else was mutating the hand. I assumed it wouldn't because I wasn't returning the hand, but was just calling the verify function to give me a True or False. The problem seems solved by simply inserting a hand = hand.copy() right under the else, but above the hand -= 1. No clue why though.


Ah, yeah I see. You can still mutate the hand, even if you don't return it. The function arguments aren't copied, they are just references to the original values, where the function was called from. That's why you need to copy the hand before you mutate it.
 

leroidys

Member
Ah sorry. I'll do that later when I get the chance.

But first I'll just insert print statements everywhere and see where the problem is occurring.

edit: The problem lied in how I verified that the word was a valid input.

Code:
def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.
    
    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
    if word not in word_list:
        return False 
    elif word in word_list:
        for i in word:
            if i not in hand.keys(): 
                return False 
            else:
                hand[i] -= 1
                if hand[i] < 0:
                    return False 
    return True

When they input a word, the play_game function calls the verify_word function. Apparently the stuff under else was mutating the hand. I assumed it wouldn't because I wasn't returning the hand, but was just calling the verify function to give me a True or False. The problem seems solved by simply inserting a hand = hand.copy() right under the else, but above the hand -= 1. No clue why though.


This might help.


KMLjOSp.png
 

Pegasus Actual

Gold Member
You probably don't want to copy the hand in the 'else if' statement. Since that's inside the loop, you'd be making an extra copy every time you check a letter, better to do it before then so it only happens once.

I'm not very familiar with Python, but yes you're modifying in place. Keep in mind you're not actually assigning hand to something, you're modifying a member (probably a poor way to phrase it) of hand. When you do a hand=hand.copy() you are are reassigning the hand variable to a new copy, which would be analogous to the B='Hello' thing.
 

tokkun

Member
Wait but in this case I did the "B = 'hello' type thing and it still mutated somehow? Unless B -= 1 is a modified in place thing. Which it might be now that I think of it.

It's not the -= operation that matters here, it's the indexing operation. When you do 'hand', that indexing operation returns a reference to a location for storing an integer in the hand data structure. If you assign a value to a reference, that is an in-place modification.
 
It's not the -= operation that matters here, it's the indexing operation. When you do 'hand', that indexing operation returns a reference to a location for storing an integer in the hand data structure. If you assign a value to a reference, that is an in-place modification.


Ah fuck that makes sense. Thanks.
 

cyborg009

Banned
So I've got a assignment working with generic linked list and I have been struggling a bit.

My class heading
Code:
public class List<E extends Comparable<E>>

So I suppose to add some numbers to a list and its suppose to sort
like
list.add(6), list.addd(3), list.add(2)

then the list will be 2,3,6 when I display it


Code:
   public void Add(E num) {
        Node temp = new Node(num);
            if(head==null){
                 head =temp;
            }
            else{
                
                lastNode().next = temp; //put at the end of the list
                Node p=head;
                while(p!=null){
                                     
                    num.compareTo(p.info);

                    p=p.next ;
                }
            }
            
    }

I'm getting the error: Object cannot be converted to E where E is a type-variable. I feel like I'm really close on this one.
 
So I've got a assignment working with generic linked list and I have been struggling a bit.

My class heading
Code:
public class List<E extends Comparable<E>>

So I suppose to add some numbers to a list and its suppose to sort
like
list.add(6), list.addd(3), list.add(2)

then the list will be 2,3,6 when I display it


Code:
   public void Add(E num) {
        Node temp = new Node(num);
            if(head==null){
                 head =temp;
            }
            else{
                
                lastNode().next = temp; //put at the end of the list
                Node p=head;
                while(p!=null){
                                     
                    num.compareTo(p.info);

                    p=p.next ;
                }
            }
            
    }

I'm getting the error: Object cannot be converted to E where E is a type-variable. I feel like I'm really close on this one.

I see a bunch of problems with this code. But to answer your specific question, what is the type of p.info?
 
E

My node class is a inner class, here it is:

Code:
    class Node<E>
{

    E info;		
    
    Node next;		

    // Create a Node object 
    Node(E x) 
    {
        info = x;	
        next = null;	
    }
}

So I'm not much of a Java person, but don't you need to write Node<E> in the definition of Add? Like change "Node temp;" to "Node<E> temp;" etc. Nothing else stands out as being the cause of the specific error you're seeing (although the function doesn't look quite right for other reasons)
 

WanderingWind

Mecklemore Is My Favorite Wrapper
Brackets is neat. Much better than CoffeeCup. With it had an auto complete function like CodeAcademy's built in whazzit.
 

WanderingWind

Mecklemore Is My Favorite Wrapper
What auto complete function are you missing? Brackets uses the same whazzit as CodeAcademy, it's called CodeMirror

So, for instance, when I do something like

.a {

is there an option or setting to have it automatically put in the closing bracket? CoffeeCup opens a drop down when I start typing something like <sc and it will auto add <script></script> I'm sure I'm not doing something right, considering I'm messing with Brackets for the first time.

EDIT: Also, test in browser. I see how to live preview, which is sexy as hell, but how do I test across other, non-Chrome browsers? Dreamweaver, CC and the like let you do that, so I assume Brackets does too. Also, I probably should just Google this one :)
 
So, for instance, when I do something like

.a {

is there an option or setting to have it automatically put in the closing bracket? CoffeeCup opens a drop down when I start typing something like <sc and it will auto add <script></script>

I'm sure I'm not doing something right, considering I'm messing with Brackets for the first time.

Make sure you have set your file type correctly (you can manually change it from bottom right if you want to).

For example, if you have a ".html" file, it should automatically have file type "HTML". Then you can just type <sc and the script option should appear. Press enter, followed by > which results in

Code:
<script></script>

However, Brackets doesn't currently support multiple types in single document, so if you are writing your CSS inside <style></style> tags or JavaScript inside <script></script> tags, you won't see code hints. That said, that kind of inline styles/scripts are bad practice anyway.
 

WanderingWind

Mecklemore Is My Favorite Wrapper
Make sure you have set your file type correctly (you can manually change it from bottom right if you want to).

For example, if you have a ".html" file, it should automatically have file type "HTML". Then you can just type <sc and the script option should appear. Press enter, followed by > which results in

Code:
<script></script>

However, Brackets doesn't currently support multiple types in single document, so if you are writing your CSS inside <style></style> tags or JavaScript inside <script></script> tags, you won't see code hints. That said, that kind of inline styles/scripts are bad practice anyway.

I had an extension that was not properly working. I restarted without extensions and the hinting returned. Cheers.

As to the script tags...yeah. I actually don't do it for JS, but I have been known to embed my CSS, which I know is no-no. Bad habit, which I should break. Truth be told, the split screen of Brackets is likely going to help me break that habit. No more switching back and forth tabs for this amateur!

EDIT: Oh, and you can Edit -> Auto Close Braces too. AND IT HIGHLIGHTS THE ACTIVE LINE. I sort of want to marry Brackets.
 
I had an extension that was not properly working. I restarted without extensions and the hinting returned. Cheers.

As to the script tags...yeah. I actually don't do it for JS, but I have been known to embed my CSS, which I know is no-no. Bad habit, which I should break. Truth be told, the split screen of Brackets is likely going to help me break that habit. No more switching back and forth tabs for this amateur!

You can also use quick edit to quickly modify your CSS

for example:

Code:
// CSS

.funny {
 background-color: red;
}

<!-- HTML -->
<div class="funny">FUN FUN FUN</div>

Place your cursor over "funny" in the HTML file and press CTRL+E and the quick edit panel should pop up
 

WanderingWind

Mecklemore Is My Favorite Wrapper
Oh.

My.

God.

Okay, so my mind is absolutely being blown. I have been operating in straight 2003 mode. So, uh, I can't find how to test in anything other than Chrome. Google is telling me that's not possible at the moment. Is there an extension I should know about? Testing in IE and Firefox is sort of a big deal. Which I assume it is for everybody, so I am likely missing something again.

EDIT2: And you can add a new rule on the fly. How did I ever live without this thing? lol.
 
Oh.

My.

God.

Okay, so my mind is absolutely being blown. I have been operating in straight 2003 mode. So, uh, I can't find how to test in anything other than Chrome. Google is telling me that's not possible at the moment. Is there an extension I should know about? Testing in IE and Firefox is sort of a big deal. Which I assume it is for everybody, so I am likely missing something again.

EDIT2: And you can add a new rule on the fly. How did I ever live without this thing? lol.

You can enable multibrowser live preview support from File -> Enable Experimental Live Preview. Then reload the project by pressing F5 (this is fixed in the next version so you don't have to reload) and now the live preview should open automatically on your default (non-Chrome) browser.

https://github.com/adobe/brackets/wiki/Live-Preview-Multibrowser

If you just want to test your project in any other browser, either set them as your default browser or just copy the URL from another browser to the other (but you'll miss the live preview functionality).

If you want even more advanced features, jump into the world of something like Grunt http://gruntjs.com/ and it's grunt-watch plugin https://github.com/gruntjs/grunt-contrib-watch#optionslivereload

There's a dedicated web dev thread here too: http://www.neogaf.com/forum/showthread.php?t=756776&page=13
 

WanderingWind

Mecklemore Is My Favorite Wrapper
You can enable multibrowser live preview support from File -> Enable Experimental Live Preview. Then reload the project by pressing F5 (this is fixed in the next version so you don't have to reload) and now the live preview should open automatically on your default (non-Chrome) browser.

https://github.com/adobe/brackets/wiki/Live-Preview-Multibrowser

If you just want to test your project in any other browser, either set them as your default browser or just copy the URL from another browser to the other (but you'll miss the live preview functionality)

Yeah, that's what I was seeing. Ah, well, you can't have everything. Still, switching to this is going to save me roughly infinite time. I wish I had discovered this last year.
 

Milchjon

Member
Anything a dumbest possible user has to know when trying to use Virtualbox to run Ubuntu on Windows 7?

No prior knowledge about virtual machines and Linux/Ubuntu.

Any possible problems/downsides?
 

maeh2k

Member
Anything a dumbest possible user has to know when trying to use Virtualbox to run Ubuntu on Windows 7?

No prior knowledge about virtual machines and Linux/Ubuntu.

Any possible problems/downsides?

Virtualbox has some issues with graphical glitches when running Linux on a Windows host.
If you want to be on the safe side, don't use the default Virtualbox disk format (.vdi or something), but use .vmdk (or something) instead. That way you can simply run the VM in vmware Player. Vmware's free Player is rather limited compared to Virtualbox (e.g. no Snapshot feature), but when it comes to actually running the VM, it's probably better.
 

poweld

Member
Virtualbox has some issues with graphical glitches when running Linux on a Windows host.
If you want to be on the safe side, don't use the default Virtualbox disk format (.vdi or something), but use .vmdk (or something) instead. That way you can simply run the VM in vmware Player. Vmware's free Player is rather limited compared to Virtualbox (e.g. no Snapshot feature), but when it comes to actually running the VM, it's probably better.

I don't think this is universal. Most of my office is running Debian in VirtualBox on Windows without issue.
 
So what's an elegant way to pull a count of unique elements out of a file stream? I was thinking of pulling individual characters, upping a counter on a delimiter, and breaking out at a newline, but that seems so amateur.

Code:
file.getline(&line, 1000000, '\n');

while(i != -1) {
    if(line.at(i) == ' ') {
        counter += 1;
    }
    else if(line.at(i) == '\n') {
        i = -1;
    }
    else {
        i += 1;
    }
}
 

Milchjon

Member
Virtualbox has some issues with graphical glitches when running Linux on a Windows host.
If you want to be on the safe side, don't use the default Virtualbox disk format (.vdi or something), but use .vmdk (or something) instead. That way you can simply run the VM in vmware Player. Vmware's free Player is rather limited compared to Virtualbox (e.g. no Snapshot feature), but when it comes to actually running the VM, it's probably better.

Looks like it's running without problems so far.
 

injurai

Banned
Anyone use Light Table as their text editor? I know it was supposed to be some big revolution in text editing. I still run with Sublime Text which I view has the proper start of this new generation of text editors.
 
C++ is a few orders of magnitude more complex than most programming languages, I could see building some cheat sheets and taking some notes for a notebook helping out.

When most people say "documentation" in programming, usually the first thing that comes to mind is "comments" and (for some contract work) "high level overviews of functionality and source code".

Generally speaking, if something looks like you won't understand it a year out, you should comment it. If it looks like something that you'll have to explain, comment it.

The ideal is to write code that's so readable, with descriptive variable and function/method names, that someone won't need comments or extra documentation to understand it. I've yet to see a moderately sized code base fully achieve this goal, but for the sake of making things you WANT to come back to and fix, adjust and tweak, it's a good thing to strive for.

thanks for the detailed response, much appreciated
 

leroidys

Member
So what's an elegant way to pull a count of unique elements out of a file stream? I was thinking of pulling individual characters, upping a counter on a delimiter, and breaking out at a newline, but that seems so amateur.

Code:
file.getline(&line, 1000000, '\n');

while(i != -1) {
    if(line.at(i) == ' ') {
        counter += 1;
    }
    else if(line.at(i) == '\n') {
        i = -1;
    }
    else {
        i += 1;
    }
}


Where do you check for uniqueness?

If you're looking to count tokens surrounded by whitespace, I don't think there's really a more elegant way than an O(n) solution. You need to account for more than just spaces and newline characters though.

EDIT: Also, this isn't actually reading from a file stream, but doing a single read into a buffer and traversing that buffer. If this is actually what you want to do, a for loop would be nicer. If you want to keep a while loop, I'd switch to a switch statement so that you can just fall through and break without resetting 'i'.

EDIT:EDIT: You're incrementing for every whitespace. So a file that contains
Code:
"                        dog                        "
would return count = 48. EDIT AGAIN: Actually if you find whitespace, you don't increment 'i', so you're just going to get an infinite loop that overflows your int until you die.

I feel like I'm not really understanding what you're trying to do though. Why are you breaking at newlines?
 

Nesotenso

Member
was going over a python exercise and was hoping someone could answer a question.

Why can't you remove items from a list while iterating over it using a for loop? Say I remove the element at index 0 at each iteration using pop and print them. Why doesn't the last remaining element get popped giving me an empty list?
 

Saprol

Member
Why can't you remove items from a list while iterating over it using a for loop? Say I remove the element at index 0 at each iteration using pop and print them. Why doesn't the last remaining element get popped giving me an empty list?
You get funny behavior if you're adding/deleting stuff in a list while iterating over it.
Code:
def do_stuff(num):
    my_list = range(num)
    for n in my_list:
        print n
        my_list.pop(0)

>do_stuff(6)
0
2
4
The Python docs recommend making a copy of the list to iterate over if you need to make modifications to the original list. Or you can try this fancy in-place solution using slice notation and list comprehensions to avoid doubling the space used.
 
Where do you check for uniqueness?

If you're looking to count tokens surrounded by whitespace, I don't think there's really a more elegant way than an O(n) solution. You need to account for more than just spaces and newline characters though.

EDIT: Also, this isn't actually reading from a file stream, but doing a single read into a buffer and traversing that buffer. If this is actually what you want to do, a for loop would be nicer. If you want to keep a while loop, I'd switch to a switch statement so that you can just fall through and break without resetting 'i'.

EDIT:EDIT: You're incrementing for every whitespace. So a file that contains
Code:
"                        dog                        "
would return count = 48. EDIT AGAIN: Actually if you find whitespace, you don't increment 'i', so you're just going to get an infinite loop that overflows your int until you die.

I feel like I'm not really understanding what you're trying to do though. Why are you breaking at newlines?

Sorry, that wasn't my implementation, just some code put up to get the idea across. I should have specified that.

I have sanitized files that have unique characters separated by white space and line breaks (basically creating columns). My idea was to open up a file, grab a line at a time, then pull the characters out by using the white space indexes around them as bounds. Here's my implementation (I already have a line before I enter the while loop):
Code:
while(1) {
    //Parse line
    while(1) {
        if(line[i] == ' ') {
            //Pull last number
            while(line[i - k] != ' ') {
                char_num[j] = line[i - k];
                j += 1;
                k -= 1;
            }
            char_num[j] = '\0';
            temp.push_back(atoi(char_num));

            i += 1;
            k = 0;
            j = 0;
        }

        else if(line[i] == '\n' || line[i] == '\0') {
            //Pull last number. Break loop.
            while(line[i - k] != '\n' && line[i - k] != '\0') {
                char_num[j] = line[i - k];
                j += 1;
                k -= 1;
            }
            char_num[j] = '\0';
            temp.push_back(atoi(char_num));

            k = 0;
            j = 0;
            break;
        }

        else {
            i += 1;
            k += 1;
        }
    }

    //Get new line
    if(file.fail()) {
        break;
    }
    i = 0;
    file.getline(line, 10000, '\n');
}
 

cyborg009

Banned
So I'm not much of a Java person, but don't you need to write Node<E> in the definition of Add? Like change "Node temp;" to "Node<E> temp;" etc. Nothing else stands out as being the cause of the specific error you're seeing (although the function doesn't look quite right for other reasons)

Thanks! Ya I need to work on everything else.
 
was going over a python exercise and was hoping someone could answer a question.

Why can't you remove items from a list while iterating over it using a for loop? Say I remove the element at index 0 at each iteration using pop and print them. Why doesn't the last remaining element get popped giving me an empty list?

Because (at least in Java and C++, probably also in Python, but not sure) looping over a collection works with iterators. An iterator is usually a class that stores the current position in the collection in some way and needs to tell when it should stop. In the case of a Python list, which is most likely a resizable array, it's probably implemented as a class that stores a pointer to the current list element and the length of the array storing the list's element. Now, if you remove an element from the list, the iterator still has the length from before the removing stored in it.
Code:
list = ["a", "b", "c", "d"]
iter = list.iterator() # Points to the first element, length is 4
iter.next()  # Now points to the second element in the list
list.remove(0) # The list is now ["b", "c", "d"], but the iterator doesn't know that
iter.next() # Points to "d"
iter.next() # Uh oh! We went past the list! Bad things happen here.
In general, removing elements can lead to all sorts of restructurings within a data structure (think of balancing search trees) that make iterators invalid.
 
So what's an elegant way to pull a count of unique elements out of a file stream? I was thinking of pulling individual characters, upping a counter on a delimiter, and breaking out at a newline, but that seems so amateur.

Code:
file.getline(&line, 1000000, '\n');

while(i != -1) {
    if(line.at(i) == ' ') {
        counter += 1;
    }
    else if(line.at(i) == '\n') {
        i = -1;
    }
    else {
        i += 1;
    }
}

I would use std::unordered_map personally.

Code:
std::unordered_map<char, int> counts;
fstream fin(file_name, fstream::in);
char ch;

while (fin >> ch)
    ++counts[ch];

If you don't care about counts, but you just want to know which characters exist, you can use an std::bitset.

Code:
std::bitset<8*sizeof(char)> chars;
fstream fin(file_name, fstream::in);
char ch;

while (fin >> ch)
    chars[(int)ch] = true;
 

Leibniz

Member
I'm finding it very hard to adapt my thinking to Logical Programming (prolog actually).

What concerns me the most is that, well, this is my last course before getting my software engineer degree.
 

wolfmat

Confirmed Asshole
If you do index-based iteration and work with offsets, you can certainly remove items from arrays in Python while iterating over them.

The following code removes all items from source by popping the first item in source into removed in each iteration step.

Code:
source = [1,2,3,4,5,6,7]
removed = []
end = len(source)
offset = 0
for i in range(0, len(source)):
    if len(removed) == end:
        break
    print("position", i, "offset", offset)
    removed.append(source.pop(i+offset))
    offset -= 1

Edit: Note that the point to note with iterators here is that the iterator is constructed, then used, just as close to the edge noted. The point is that the iterator is immutable if you use it naively (so with the "for i in range(0, 5)" case, i will always go up to 5 even if you attempt to manipulate). If you want to break out of this, you should roll your own iteration code.
Example for the stated immutability:
Code:
for i in range(0,5):
    print("in. i: "+str(i))
    i += 1
    print("out. i: "+str(i))
Although i is being incremented at the end of the loop, the iterator setting "snaps it back" to the next iter value each time.
 

injurai

Banned
I'm finding it very hard to adapt my thinking to Logical Programming (prolog actually).

What concerns me the most is that, well, this is my last course before getting my software engineer degree.

Are you taking that as an elective. Prolog seems like like a language that history has passed by.
 
I would use std::unordered_map personally.

Code:
std::unordered_map<char, int> counts;
fstream fin(file_name, fstream::in);
char ch;

while (fin >> ch)
    ++counts[ch];

If you don't care about counts, but you just want to know which characters exist, you can use an std::bitset.

Code:
std::bitset<8*sizeof(char)> chars;
fstream fin(file_name, fstream::in);
char ch;

while (fin >> ch)
    chars[(int)ch] = true;

I knew there was something hidden in the standard libraries. Thanks for the ideas.
 

tokkun

Member
If you don't care about counts, but you just want to know which characters exist, you can use an std::bitset.

Code:
std::bitset<8*sizeof(char)> chars;
fstream fin(file_name, fstream::in);
char ch;

while (fin >> ch)
    chars[(int)ch] = true;

That's only 8 bits; you are going to need 256.
 
If you do index-based iteration and work with offsets, you can certainly remove items from arrays in Python while iterating over them.

The following code removes all items from source by popping the first item in source into removed in each iteration step.

Code:
source = [1,2,3,4,5,6,7]
removed = []
end = len(source)
offset = 0
for i in range(0, len(source)):
    if len(removed) == end:
        break
    print("position", i, "offset", offset)
    removed.append(source.pop(i+offset))
    offset -= 1

Edit: Note that the point to note with iterators here is that the iterator is constructed, then used, just as close to the edge noted. The point is that the iterator is immutable if you use it naively (so with the "for i in range(0, 5)" case, i will always go up to 5 even if you attempt to manipulate). If you want to break out of this, you should roll your own iteration code.
Example for the stated immutability:
Code:
for i in range(0,5):
    print("in. i: "+str(i))
    i += 1
    print("out. i: "+str(i))
Although i is being incremented at the end of the loop, the iterator setting "snaps it back" to the next iter value each time.

Right, that works of course. I forgot to mention that.
 

Phrynobatrachus

Neo Member
I could use some help regarding linked lists in C. I've been given two structures, and have to create a linked list where each element contains it's own linked list. Here's my current code. I don't have trouble created the main linked list, but I can't figure out how to get the other ones initialized and linked correctly to those elements. Each element of the 2d array I'm reading in is an edge structure, and the rows of the array correspond to the sublists of the main list.
 

upandaway

Member
I could use some help regarding linked lists in C. I've been given two structures, and have to create a linked list where each element contains it's own linked list. Here's my current code. I don't have trouble created the main linked list, but I can't figure out how to get the other ones initialized and linked correctly to those elements. Each element of the 2d array I'm reading in is an edge structure, and the rows of the array correspond to the sublists of the main list.
I don't really know how to look at your code, but if I understand what you mean, creating a linked list or creating a linked list of linked lists are both dependent on the same two operations:
Say your list nodes look like this
Code:
struct Node {
    struct Node *next;
    void *data;
}

Then you just need to implement
Code:
struct Node ** newList();
void append(struct Node **list, void *data);

And then create one list, iterate over it, and for every node you iterate over do "node->data = newList();"

edit: forgot newList() has to return a ** pointer
 

Leibniz

Member
Are you taking that as an elective. Prolog seems like like a language that history has passed by.

Oh no, I wish it was elective. It's a mandatory course.

I work in SAP implementatinos so believe me, Prolog is like the last thing I'd take would it be an elective one, haha.
 
Top Bottom