Monthly Archives: April 2013

Coding Bat: Python. List-1

All solutions were successfully tested on 16 April 2013.

first_last6:

def first_last6(nums):
  return nums[0] == 6 or nums[-1] == 6

same_first_last:

def same_first_last(nums):
  return len(nums) >= 1 and nums[0] == nums[-1]

make_pi:

def make_pi():
  return [3, 1, 4]

common_end:

def common_end(a, b):
  return a[0] == b[0] or a[-1] == b[-1]

sum3:

def sum3(nums):
  #return nums[0] + nums[1] + nums[2]
  return sum(nums)

Either way works. The version I’ve commented out is less elegant, though.

rotate_left3:

def rotate_left3(nums):
  return [nums[1], nums[2], nums[0]] 

reverse3:

def reverse3(nums):
  #return [nums[2], nums[1], nums[0]]
  return nums[::-1]

Again, the second version is more elegant or, as some phrase it, more “pythonic”.

max_end3:

def max_end3(nums):
  m = max(nums[0], nums[2])
  return [m, m, m]

For matters of comparison, here is the solution from the website:

def max_end3(nums):
  big = max(nums[0], nums[2])
  nums[0] = big
  nums[1] = big
  nums[2] = big
  return nums

It is less expressive and, frankly, a bit painful to look at. A much nicer way to assign “big” to three variables at once would be one of the two following ways:

def max_end3(nums):
  big = max(nums[0], nums[2])
  #nums[0], nums[1], nums[2] = big, big, big
  nums[0], nums[1], nums[2] = (big, ) * 3
  return nums

sum2:

def sum2(nums):
  if len(nums) == 0:
    return 0
  if len(nums) == 1:
    return nums[0]
  return nums[0] + nums[1]

middle_way:

def middle_way(a, b):
  return [a[1], b[1]]

make_ends:

def make_ends(nums):
  return [nums[0], nums[-1]]

has23:

def has23(nums):
  return 2 in nums or 3 in nums

Do you remember what this looked like in Java?

Coding Bat: Python. String-1

All solutions were successfully tested on 15 April 2013.

hello_name:

def hello_name(name):
  return "Hello " + name + "!"

make_abba:

def make_abba(a, b):
  return a + b + b + a

make_tags:

def make_tags(tag, word):
  return "<" + tag + ">" + word + "</" + tag + ">"

make_out_word:

def make_out_word(out, word):
  return out[:2] + word + out[2:]

extra_end:

def extra_end(str):
  return str[-2:] * 3

The asterisk is overloaded in Python, as you see in this example. An alternative solution would be to concatenate with “+”, as you’ve seen it before.

first_two:

def first_two(str):
  if len(str) <= 2:
    return str
  return str[:2]

first_half:

def first_half(str):
  return str[:len(str)/2]

without_end:

def without_end(str):
  return str[1:-1]

combo_string:

def combo_string(a, b):
  if len(a) > len(b):
    return b + a + b
  return a + b + a

non_start:

def non_start(a, b):
  return a[1:] + b[1:]

left2:

def left2(str):
  return str[2:] + str[:2]

Coding Bat: Python. Warmup-2

All solutions were successfully tested on 13 April 2013.

string_times:

def string_times(str, n):
  return str * n

front_times:

def front_times(str, n):
  if len(str) < 3:
    return str * n
  return str[:3] * n

string_bits:

def string_bits(str):
  result = ''
  for n in range(0, len(str)):
    if n%2 == 0:
      result += str[n]
  return result

string_splosion:

def string_splosion(str):
  result = ''
  for n in range(0,len(str)+1):
    result += str[:n]
  return result

last2:

def last2(str):    
  count = 0
  for i in range(len(str)-2):
    if str[i:i+2] == str[-2:]:
      count += 1   
  return count

Below I show the solution from the website, which is overambitous since there is no need to specifically process cases in which the input string is too short. The reason is that the for loop takes the length of the string into account. If the range was given as an absolute number, say, range(10), then a separate check that the string is long enough would have been necessary.

def last2(str):
  # Screen out too-short string case.
  if len(str) < 2:
    return 0
  
  # last 2 chars, can be written as str[-2:]
  last2 = str[len(str)-2:]
  count = 0
  
  # Check each substring length 2 starting at i
  for i in range(len(str)-2):
    sub = str[i:i+2]
    if sub == last2:
      count = count + 1

  return count

array_count9:

def array_count9(nums):
  count = 0
  for element in nums:
    if element == 9:
      count += 1
  return count

Please note that Python allows you to conveniently name variables, which makes the resulting code a lot more readable. In Java you would probably stick to variable names like “i” due to the fact that you have to repeat them so often. Below is a solution in Java to illustrate this issue. Imagine you would have written “element” instead of “i”:

public int arrayCount9(int[] nums) {
	int result = 0;
	for (int i = 0; i < nums.length; i++) {
		if (nums[i] == 9)
			result++;
	}
	return result;
}

array_front9:

def array_front9(nums):
  for element in nums[:4]:
    if element == 9:
      return True
  return False

Again, there is a slight inconvenience in the solution given on Coding Bat:

def array_front9(nums):
  # First figure the end for the loop
  end = len(nums)
  if end > 4:
    end = 4
  
  for i in range(end):  # loop over index [0, 1, 2, 3]
    if nums[i] == 9:
      return True
  return False

It is superfluous to consider the length of the array since the slice [:4] will be processed at most up to but not including position 4. If the array is shorter, the procedure will simply stop. I have seen pythonistas defend similar code by referring to the Zen of Python, particularly the line “Explicit is better than implicit.” However, I consider this to be a bizarre interpretation. If you write code like that you only show that you have not yet “grokked” Python and instead translate from another language. You can write Java in Python, but not the other way round, so if you’ve got the option to write more elegant code, why wouldn’t you want to make use of that opportunity?

array123:

def array123(nums):
  for i in range(len(nums)-2):
    if nums[i] == 1 and nums[i+1] == 2 and nums[i+2] == 3:
      return True
  return False

But, wait, this can be done more nicely:

def array123(nums):
  for i in range(len(nums)-2):
    if nums[i:i+3] == [1,2,3]:
      return True
  return False

string_match:

def string_match(a, b):
  min_length = min(len(a), len(b))
  
  count = 0  
  for i in range(min_length-1):
    if a[i:i+2] == b[i:i+2]:
      count += 1
  return count

Coding Bat: Python. Warmup-1

All solutions were successfully tested on 13 April 2013.

sleep_in:

def sleep_in(weekday, vacation):
  return not weekday or vacation

As you can already see, it’s pleasant to write Python code, and this language is very readable, too. Just compare this method with the equivalent in Java:

public boolean sleepIn(boolean weekday, boolean vacation) {
  return (! weekday || vacation);
}

monkey_trouble:

def monkey_trouble(a_smile, b_smile):
  return a_smile and b_smile or not a_smile and not b_smile

sum_double:

def sum_double(a, b):
  if a == b:
    return a * 4
  return a + b

diff21:

def diff21(n):
  if n > 21:
    return abs(n-21) * 2
  return abs(n-21)

parrot_trouble:

def parrot_trouble(talking, hour):
  return talking and (hour < 7 or hour > 20)

makes10:

def makes10(a, b):
  return a + b == 10 or a == 10 or b == 10

near_hundred:

def near_hundred(n):
  return abs(n-100) <= 10 or abs(n-200) <= 10

pos_neg:

def pos_neg(a, b, negative):
  if negative:
    return a < 0 and b < 0
  return a * b < 0

I took a shortcut in the last line since the result will be negative if one of the numbers is negative, and the other positive. The sample solution on the website is more verbose:

def pos_neg(a, b, negative):
  if negative:
    return (a < 0 and b < 0)
  else:
    return ((a < 0 and b > 0) or (a > 0 and b < 0))

not_string:

def not_string(str):
  if str[:3] == "not":
    return str
  return "not " + str

missing_char:

def missing_char(str, n):
  return str[:n] + str[n+1:]

front_back:

def front_back(str):
  if len(str) == 0 or len(str) == 1:
    return str
  return str[-1] + str[1:-1] + str[0]

front3:

def front3(str):
  if len(str) < 3:
    return str * 3
  return str[:3] * 3

Coding Bat: Python Solutions

I was quite surprised by the relatively high interest people seem to have in my Coding Bat: Java solutions, but I’m glad that others find them helpful. I therefore decided to upload my Coding Bat: Python solutions as well. The Python section on Coding Bat is not nearly as extensive as their Java counterpart. Still, for anyone wanting to get started with programming, the exercises offer a gentle introduction to basic programming concepts.

I have gone through all exercises, and I will publish all solutions. There is not much need for commentary, but I will point out a few things. However, please try to solve the problems yourself. There is little point in copy & pasting my solutions just to earn a “gold star” at that website.

If you’re starting out with programming and think you want to pick up a “real” language like Java first, I can only encourage you to compare a few of the Python solutions with their Java counterpart. At the very least, you’ll probably find that Python code is more readable. As you gain more experience, you might also come to the conclusion that it’s more enjoyable to write Python than Java code.

I’ll go through all sections sequentially, and intend to post one section per day.