Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Lindsay Barrett
seal-mask
.a{fill-rule:evenodd;}techdegree
Lindsay Barrett
Python Web Development Techdegree Student 7,357 Points

Hello, need assistance with this question

I am stuck on this question. I am unsure of the following.

1) How to add multiple arguments in the function call 2) How to add the integer items together.

Assistance is appreciated.

new=[]

def combiner(item):
    if isinstance(item,int):
        item+=item
        new.append(item[:-1]) 
    if isinstance(item,str):
        new.append(item)       
    print(','.join(new))

combiner(8,4, "hello")
Leandro Inumerable
Leandro Inumerable
11,553 Points

Hi Lindsay,

You might have missed out a key part of the question. The function actually just takes one argument - a list - and within that list, there will be strings and numbers. It states:

"Create a function named combiner that takes a single argument, which will be a list made up of strings and numbers."

The way to approach this problem would be to iterate through the given input (the list) and then identify if the item is a string or an int/float. And then process it depending on the item type (which you already have in your current code).

3 Answers

Alex Koumparos
seal-mask
.a{fill-rule:evenodd;}techdegree
Alex Koumparos
Python Development Techdegree Student 36,887 Points

Hi Lindsay,

Your first issue is with your use of the isinstance built-in function. Let's revisit the documentation for this function to ensure we're on the same page:

isinstance(object, classinfo)
Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof...

We want to pass isinstance a value of some type, and then compare it to a value of a known type (or to the known type itself) so that we can behave differently for values of ints and strings.

As the challenge tells us, our function input is a list, whose elements are some combination of numbers (possibly ints, possibly floats) and strings:

...takes a single argument, which will be a list made up of strings and numbers.

A list is neither an int nor a string. Therefore any comparison to either int or string will evaluate to False, as illustrated here:

>>> l = [1, 'hello']
>>> isinstance(l, int)
False
>>> isinstance(l, str)
False
>>> isinstance(l, list)
True

To proceed with this question, consider approaching this using the most simple concepts possible:

  • you know you are getting a list as an input;
  • you can use a for loop to iterate through a list;
  • you can check the type of each element in the list (instead of checking the type of the list itself);
  • you can assign values to variables (you might consider keeping a strings variable: a list of all the strings you've seen so far; and a number variable: the running total of the numbers so far;
  • you can use join() to combine the strings in the strings variable;
  • you can use str() to convert a number to a string;
  • you can use + to concatenate two strings.

If you've made it to object oriented Python, all of the above concepts should be familiar to you. If any are not, let me know and I'll give you some pointers.

As for your specific questions:

  1. How to add multiple arguments in the function call

I'm not sure exactly what you are asking here, you want to add values while calling a function? If so, you can do it like this:

>>> my_function(3 + 5)    # this is equivalent to calling my_function(8)

Remember though, you will not call your function. You just write the function. Treehouse will call your function in the background with (probably multiple) secret values. As such, you need to write your function in such a way that it can work with any valid input (a valid input, in this case, being defined in the question as "a list made up of strings and numbers").

  1. How to add the integer items together

First, remember that you are not necessarily just going to get integers. The question specifically states "numbers" not integers, and then shows you an example that includes both integers and floats:

For example, with the input ["apple", 5.2, "dog", 8], combiner would return "appledog13.2"

Python can handle adding floats and integers without needing you to manually typecast the values. It will treat any sum of ints and floats as a float: For example:

>>> total = 1 + 1
>>> type(total)    # an int plus an int is an int
<class 'int'>
>>> total = 1 + 3.14
>>> type(total)   # an int plus a float is a float
<class 'float'>
>>> total = 2.72 + 1
>>> type(total)   # a float plus an int is a float
<class 'float'>

Hope this points you in the right direction.

Cheers

Alex

Lindsay Barrett
seal-mask
.a{fill-rule:evenodd;}techdegree
Lindsay Barrett
Python Web Development Techdegree Student 7,357 Points

@AlexKoumparos

Okay, the below works, but it is clunky. Any thoughts on how to condense?

strings=[]
numbers=[]
combined=[]

def combiner(item):

    for value in item:
        if isinstance(value,int):
            numbers.append(value) 
        if isinstance(value,float):
            numbers.append(value)
        if isinstance(value,str):
            strings.append(value)        


    new = ''.join(strings)
    combined.append(new)

    total = sum(numbers)
    combined.append(str(total))
    final = ''.join(combined)

    print(final)


combiner([1,"hello",2, 4.5,"dog"])
Alex Koumparos
seal-mask
.a{fill-rule:evenodd;}techdegree
Alex Koumparos
Python Development Techdegree Student 36,887 Points

Hi Lindsay,

Glad I was able to be of some help.

I would move your variables into your function (but still outside the for loop). Global variables are generally considered a bad idea, and you don't need them outside of your function.

You only need to do one isinstance check: remember that the question promises that it will give you only strings and numbers, so if the instance is string, it's a string. If not, it must be a number. Also notice that in your code you do the same thing regardless of what type of number you have, so why bother checking which kind of number it is? Once you've determined whether the value is a string or not, you can branch your code with if/else to handle the two different behaviours.

You never use the individual numbers after you first see them. So you don't gain anything by preserving them in a list. Instead, if you had a running_total variable for your numbers (initialised as 0), you could just update that number by adding the current number every time you see one. Then you save yourself the trouble of summing all the numbers at the end.

The same is true of the strings. Instead of creating a list, then appending to it, then joining it, you could start with an empty string variable and then just concatenate each string to your variable each time you encounter a string.

You don't need to join() twice. Once you have joined your strings into one single string, you can just use string concatenation to add the number to the string: combined = my_joined_string + str(my_running_total). This assumes you decide to keep your variables as lists. If you use string/number type variables instead you don't need any joins at all.

You don't need the combined variable. It's sufficient to maintain the numbers and strings variables during your processing of the input data (i.e., the bit inside the for loop). Once your loop is finished, you can just use your new variable. Or, if you change your strings variable to a string instead of a list, you can just use that: add the final running total number to the end of your strings variable and return that.

Finally, you have a critical bug that I'm surprised the challenge tester missed: You have no return statement. The challenge tells you to return the string, but you just print it. Unlike some other languages that return the last value that was evaluated, Python returns None if not given an explicit return statement. To fix this you just need to replace your print statement with a return statement.

Oh, and finally finally, you don't need to call your function in the code you submit. The challenge tester will call your function with its own values.

Hope those hints are of use. I think I was able to reduce your lines of code by about 50% using these suggestions.

Cheers

Alex