running ruby on terminal gives me a different output than leetcode - ruby

I'm practicing leetcode and checking other people's solutions for the same exercise on my terminal gives a totally different output than expected. If I run it on leetcode it says the answer is correct...
What might be causing this?
reversing the array of chars - ["h","e","l","l","o"] - like so:
def reverse_string(s)
len = s.length
(0...len/2).each { |i|
temp = s[i]
swap_index = len-i-1
s[i] = s[swap_index]
s[swap_index] = temp
}
end
p reverse_string([["h","e","l","l","o"]])
output in my terminal -- 0...2
output in leetcode is as expected - ["o","l","l","e","h"]
Why does this happen?
thanks

Ruby's p function will print the value you pass to it.
The value you are choosing to pass to it is the return value of reverse_string.
You should add a line to the end of reverse_string that specifies what you want to return from it. In this case the line can simply consist of s. You don't even need an explict return in this case.

Related

I am not getting the desired output with my python code

<code>def CheckNumber(MyList, number):
counter=0
while number!=0:
for i,element in enumerate(MyList):
if number%10==element:
del MyList[i]
else:
continue
number = number/10
if len(MyList)==0:
return 1
else:
return 2
print("Program to print all the possible combinations of a number")
MyNumber = int(input("Enter the number: "))
MyList = []
while MyNumber!=0:
MyList.append(MyNumber%10)
MyNumber=int(MyNumber/10)
MyLimit = 10**(len(MyList)-1)
for i in range(MyLimit, MyLimit*10):
answer = CheckNumber(MyList, i)
if answer == 1:
print(i)
else:
continue`</code>
I am a beginner at programming and I was trying to write a code to print all the possible combinations of a number. If user enters a 3 digit number the program will check all the three digit numbers to find possible combinations but instead it gives all the numbers as output. For example if user enters 12 then the output should be 12 21 but instead it shows every number from 10 to 99.
As far as I know everything is working fine but the results are not as I expect.
This is a pass-by-reference vs pass-by-value problem. What that means is when you pass a list to a function in python you are not passing the values in that list, you are passing the list itself, or rather its location in memory. So when you are modifying MyList in your CheckNumber function you are actually modifying the MyList variable globally. This is not true for primitive types which is why modifying number does not change i in the for loop. Quick example:
def foo(my_list):
my_list.append('world')
print(my_list)
a = []
foo(a) # this will print out 'world'
print(a) # this will print out 'world'
b = 'hello'
foo(b.copy()) # This will print out 'hello world'
print(b) # Here we have not passed b directly into foo,
# but instead passed a copy, so this will just print out 'hello' as b
# has not been modified
To summarize variable are stored in a specific location in memory. When you pass-by-reference you are passing a long that location in memory so you variable will be mutated. If you pass-by-value, you function will create a new variable and store a copy of the data so you will not mutate your outer variable. In other languages you can specify which way to pass in a variable but afaik you cannot in python.
With that out of the way this is a very easy fix. You don't want to modify your original MyList so just make a copy of it and pass that into the function. You also forgot to cast number/10 to int in the CheckNumber function. The working code should look like this:
def CheckNumber(MyList, number):
counter=0
while number!=0:
for i,element in enumerate(MyList):
if number%10==element:
del MyList[i]
else:
continue
number = int(number/10)
if len(MyList)==0:
return 1
else:
return 2
print("Program to print all the possible combinations of a number")
MyNumber = int(input("Enter the number: "))
MyList = []
while MyNumber!=0:
MyList.append(MyNumber%10)
MyNumber=int(MyNumber/10)
MyLimit = 10**(len(MyList)-1)
for i in range(MyLimit, MyLimit*10):
answer = CheckNumber(MyList.copy(), i)
if answer == 1:
print(i)
else:
continue
More info on pass-by-reference:
What's the difference between passing by reference vs. passing by value?
https://blog.penjee.com/passing-by-value-vs-by-reference-java-graphical/
https://courses.washington.edu/css342/zander/css332/passby.html

Indexes of strings in Ruby

My current project has me converting Ruby into Node.js. I've never worked with Ruby before this and so I'm still trying to learn all the syntactical differences. Currently, I'm a bit confused about this snippet:
myUri = Addressable::URI.parse(original_path)
idx = original_path.index(myUri.path)
hit.props[:path] = original_path[idx..original_path.length-1]
else
hit.is_invalid = true
So, I understand that we are parsing the original_path.
Then, we are getting the index of the myUri.path inside of the original_path, which I believe will return a number.
The next line is what's confusing me. I know I'm setting [:path] to something, but I don't understand what. I think that it's a modified version of original_path but I'm not understanding how its being modified.
original_path[idx..original_path.length-1] accesses string using a range.
See a range exaple
(1..4).to_a
# [1,2,3,4]
Range string/array access takes a part of the array/string that is between range boundaries. In this case - between idx (that is the beginning of myUri.path) and the end of the string.
See below:
a = 'abcd'
# => "abcd"
a[1..a.size-1]
# => "bcd"
Docs

Can someone explain how this ruby basic-calculator code handles addition and subtraction?

So I was working on a Codewars problem here, and found some code posted to Github that works out-of-the-box. Problem is, I don't understand how part of it works. Here are the Codewars directions:
Description:
Create a simple calculator that given a string of operators (+ - * and /) and numbers separated by spaces returns the value of that expression
Example:
Calculator.new.evaluate("2 / 2 + 3 * 4 - 6") # => 7
Remember about the order of operations! Multiplications and divisions have a higher priority and should be performed left-to-right. Additions and subtractions have a lower priority and should also be performed left-to-right.
Here's the code:
class Calculator
def evaluate(string)
operator_stack = []
number_stack = []
string.split(" ").each do |token|
if /\d/.match(token)
number_stack << token.to_i
elsif operator_stack.length > 0 && /[*]|[\/]/.match(operator_stack[-1])
x, y = number_stack.pop, number_stack.pop
temp_result = y.send(operator_stack.pop, x)
number_stack << temp_result
operator_stack << token
else
operator_stack << token
end
end
while(number_stack.length > 0 && operator_stack.length > 0)
x, y = number_stack.shift, number_stack.shift
temp_result = x.send(operator_stack.shift,y)
number_stack.unshift(temp_result)
end
return number_stack[0]
end
end
Now I've learned enough Ruby that I can read through and understand what the various functions do, but when it comes to the mathematical operations the code does, I don't see where or how it handles addition and subtraction. There is some regex that's used to match for multiplication and division present in this line:
elsif operator_stack.length > 0 && /[*]|[\/]/.match(operator_stack[-1])
But since I don't see the plus or minus sign anywhere in the code, I don't get how it performs those operations. Can anyone help?
BTW, I'm done with the Codewars problem and have moved on. I also discovered you can solve this calculator problem with "instance_eval string", which blew my mind when I first saw it. But, it makes sense after reading through what I found here. I should have guessed that there was a one-liner that would work as a basic calculator :)
I would still like to know how this code handles addition and subtraction. Can anyone enlighten me?
The actual operations are performed in these lines:
temp_result = y.send(operator_stack.pop, x)
and later
temp_result = x.send(operator_stack.shift,y)
which says "send the operator_stack.shift/pop message with parameter y to objectx, which is basically the same as doing x <operator> y where <operator> is the operator on top of operator_stack

What is the pythonic way to print values right aligned?

I've a list of strings which I want to group by their suffix and then print the values right-aligned, padding the left side with spaces.
What is the pythonic way to do that?
My current code is:
def find_pos(needle, haystack):
for i, v in enumerate(haystack):
if str(needle).endswith(v):
return i
return -1
# Show only Error and Warning things
search_terms = "Error", "Warning"
errors_list = filter(lambda item: str(item).endswith(search_terms), dir(__builtins__))
# alphabetical sort
errors_list.sort()
# Sort the list so Errors come before Warnings
errors_list.sort(lambda x, y: find_pos(x, search_terms) - find_pos(y, search_terms))
# Format for right-aligning the string
size = str(len(max(errors_list, key=len)))
fmt = "{:>" + size + "s}"
for item in errors_list:
print fmt.format(item)
An alternative I had in mind was:
size = len(max(errors_list, key=len))
for item in errors_list:
print str.rjust(item, size)
I'm still learning Python, so other suggestions about improving the code is welcome too.
Very close.
fmt = "{:>{size}s}"
for item in errors_list:
print fmt.format(item, size=size)
The two sorting steps can be combined into one:
errors_list.sort(key=lambda x: (x, find_pos(x, search_terms)))
Generally, using the key parameter is preferred over using cmp. Documentation on sorting
If you are interested in the length anyway, using the key parameter to max() is a bit pointless. I'd go for
width = max(map(len, errors_list))
Since the length does not change inside the loop, I'd prepare the format string only once:
right_align = ">{}".format(width)
Inside the loop, you can now do with the free format() function (i.e. not the str method, but the built-in function):
for item in errors_list:
print format(item, right_align)
str.rjust(item, size) is usually and preferrably written as item.rjust(size).
You might want to look here, which describes how to right-justify using str.rjust and using print formatting.

Pythonic ways to use 'else' in a for loop [duplicate]

This question already has answers here:
Why does python use 'else' after for and while loops?
(24 answers)
Closed 7 months ago.
I have hardly ever noticed a python program that uses else in a for loop.
I recently used it to perform an action based on the loop variable condition while exiting; as it is in the scope.
What is the pythonic way to use an else in a for loop? Are there any notable use cases?
And, yea. I dislike using break statement. I'd rather set the looping condition complex. Would I be able to get any benefit out of it, if I don't like to use break statement anyway.
Worth noting that for loop has an else since the language inception, the first ever version.
What could be more pythonic than PyPy?
Look at what I discovered starting at line 284 in ctypes_configure/configure.py:
for i in range(0, info['size'] - csize + 1, info['align']):
if layout[i:i+csize] == [None] * csize:
layout_addfield(layout, i, ctype, '_alignment')
break
else:
raise AssertionError("unenforceable alignment %d" % (
info['align'],))
And here, from line 425 in pypy/annotation/annrpython.py (clicky)
if cell.is_constant():
return Constant(cell.const)
else:
for v in known_variables:
if self.bindings[v] is cell:
return v
else:
raise CannotSimplify
In pypy/annotation/binaryop.py, starting at line 751:
def is_((pbc1, pbc2)):
thistype = pairtype(SomePBC, SomePBC)
s = super(thistype, pair(pbc1, pbc2)).is_()
if not s.is_constant():
if not pbc1.can_be_None or not pbc2.can_be_None:
for desc in pbc1.descriptions:
if desc in pbc2.descriptions:
break
else:
s.const = False # no common desc in the two sets
return s
A non-one-liner in pypy/annotation/classdef.py, starting at line 176:
def add_source_for_attribute(self, attr, source):
"""Adds information about a constant source for an attribute.
"""
for cdef in self.getmro():
if attr in cdef.attrs:
# the Attribute() exists already for this class (or a parent)
attrdef = cdef.attrs[attr]
s_prev_value = attrdef.s_value
attrdef.add_constant_source(self, source)
# we should reflow from all the reader's position,
# but as an optimization we try to see if the attribute
# has really been generalized
if attrdef.s_value != s_prev_value:
attrdef.mutated(cdef) # reflow from all read positions
return
else:
# remember the source in self.attr_sources
sources = self.attr_sources.setdefault(attr, [])
sources.append(source)
# register the source in any Attribute found in subclasses,
# to restore invariant (III)
# NB. add_constant_source() may discover new subdefs but the
# right thing will happen to them because self.attr_sources
# was already updated
if not source.instance_level:
for subdef in self.getallsubdefs():
if attr in subdef.attrs:
attrdef = subdef.attrs[attr]
s_prev_value = attrdef.s_value
attrdef.add_constant_source(self, source)
if attrdef.s_value != s_prev_value:
attrdef.mutated(subdef) # reflow from all read positions
Later in the same file, starting at line 307, an example with an illuminating comment:
def generalize_attr(self, attr, s_value=None):
# if the attribute exists in a superclass, generalize there,
# as imposed by invariant (I)
for clsdef in self.getmro():
if attr in clsdef.attrs:
clsdef._generalize_attr(attr, s_value)
break
else:
self._generalize_attr(attr, s_value)
If you have a for loop you don't really have any condition statement. So break is your choice if you like to abort and then else can serve perfectly to handle the case where you were not happy.
for fruit in basket:
if fruit.kind in ['Orange', 'Apple']:
fruit.eat()
break
else:
print 'The basket contains no desirable fruit'
Basically, it simplifies any loop that uses a boolean flag like this:
found = False # <-- initialize boolean
for divisor in range(2, n):
if n % divisor == 0:
found = True # <-- update boolean
break # optional, but continuing would be a waste of time
if found: # <-- check boolean
print n, "is composite"
else:
print n, "is prime"
and allows you to skip the management of the flag:
for divisor in range(2, n):
if n % divisor == 0:
print n, "is composite"
break
else:
print n, "is prime"
Note that there is already a natural place for code to execute when you do find a divisor - right before the break. The only new feature here is a place for code to execute when you tried all divisor and did not find any.
This helps only in conjuction with break. You still need booleans if you can't break (e.g. because you looking for the last match, or have to track several conditions in parallel).
Oh, and BTW, this works for while loops just as well.
any/all
Nowdays, if the only purpose of the loop is a yes-or-no answer, you might be able to write it much shorter with the any()/all() functions with a generator or generator expression that yields booleans:
if any(n % divisor == 0
for divisor in range(2, n)):
print n, "is composite"
else:
print n, "is prime"
Note the elegancy! The code is 1:1 what you want to say!
[This is as effecient as a loop with a break, because the any() function is short-circuiting, only running the generator expression until it yeilds True. In fact it's usually even faster than a loop. Simpler Python code tends to have less overhear.]
This is less workable if you have other side effects - for example if you want to find the divisor. You can still do it (ab)using the fact that non-0 value are true in Python:
divisor = any(d for d in range(2, n) if n % d == 0)
if divisor:
print n, "is divisible by", divisor
else:
print n, "is prime"
but as you see this is getting shaky - wouldn't work if 0 was a possible divisor value...
Without using break, else blocks have no benefit for for and while statements. The following two examples are equivalent:
for x in range(10):
pass
else:
print "else"
for x in range(10):
pass
print "else"
The only reason for using else with for or while is to do something after the loop if it terminated normally, meaning without an explicit break.
After a lot of thinking, I can finally come up with a case where this might be useful:
def commit_changes(directory):
for file in directory:
if file_is_modified(file):
break
else:
# No changes
return False
# Something has been changed
send_directory_to_server()
return True
Perhaps the best answer comes from the official Python tutorial:
break and continue Statements, and else Clauses on Loops:
Loop statements may have an else
clause; it is executed when the loop
terminates through exhaustion of the
list (with for) or when the condition
becomes false (with while), but not
when the loop is terminated by a break
statement
I was introduced to a wonderful idiom in which you can use a for/break/else scheme with an iterator to save both time and LOC. The example at hand was searching for the candidate for an incompletely qualified path. If you care to see the original context, please see the original question.
def match(path, actual):
path = path.strip('/').split('/')
actual = iter(actual.strip('/').split('/'))
for pathitem in path:
for item in actual:
if pathitem == item:
break
else:
return False
return True
What makes the use of for/else so great here is the elegance of avoiding juggling a confusing boolean around. Without else, but hoping to achieve the same amount of short-circuiting, it might be written like so:
def match(path, actual):
path = path.strip('/').split('/')
actual = iter(actual.strip('/').split('/'))
failed = True
for pathitem in path:
failed = True
for item in actual:
if pathitem == item:
failed = False
break
if failed:
break
return not failed
I think the use of else makes it more elegant and more obvious.
A use case of the else clause of loops is breaking out of nested loops:
while True:
for item in iterable:
if condition:
break
suite
else:
continue
break
It avoids repeating conditions:
while not condition:
for item in iterable:
if condition:
break
suite
Here you go:
a = ('y','a','y')
for x in a:
print x,
else:
print '!'
It's for the caboose.
edit:
# What happens if we add the ! to a list?
def side_effect(your_list):
your_list.extend('!')
for x in your_list:
print x,
claimant = ['A',' ','g','u','r','u']
side_effect(claimant)
print claimant[-1]
# oh no, claimant now ends with a '!'
edit:
a = (("this","is"),("a","contrived","example"),("of","the","caboose","idiom"))
for b in a:
for c in b:
print c,
if "is" == c:
break
else:
print

Resources