# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# Introduction
# ==========
#
# The goal of this book is help familiarize engineers with the most common features of Python and the most common libraries that will be used. Most engineers are already familiar with a language like Matlab or VBA, so the very basics of programming won't be covered.

# ## A Quick Example

# Python is an incredibly dynamic language that lets you write complex statements quickly and compactly. Let's say you had a table of prices for common things per year and you wanted to find the year when buying all of them would be cheapest. You can do that in just one line:

# +
# I do need to set up my data
prices = {
    'Cell Phone': [250, 255, 260, 240, 231],
    'Laptop': [801, 850, 760, 925, 860],
    'Headphones': [320, 255, 301, 360, 293],
}

year, min_price = min([(year, sum(prices[name][year] for name in prices)) for year in range(5)], key=lambda x: x[1])

print("{0}: ${1}".format(year, min_price))
# In Python >3.6 -> print(f"{year}: ${min_price}")
# -

# For now, the above might look complex, however in the chapter on generators we will break the example down piece by piece.

# ## Indentation is Everything

# For Matlab users, Python can be very similar. One of the major differences, however, is that Python determines the end of its functions and clauses by indentation, rather than a defined end keyword. Take this Matlab code for example:

# ```matlab
# function y = is_even(x)
# % Return whethor not a number is even
# % Yes, I know I could just return mod(x, 2), but that wouldn't show indentation as well
# if mod(x, 2) == 0
#     y = 1
# else
#     y = 0
# end 
# end
# ```

# Note that the indentation of the `if` clause is really only for readability. The parser is looking for an `else` or `end` keyword to stop reading. In Python, it would look more like this:

# +
def is_even(x):
    if x % 2 == 0:
        return 1
    else:
        return 0
    
is_even(3)


# -

# Here, anytime there is a colon, the next level must be indented. This is how Python determines where a function or clause begins and ends. When the indentation level moves back out, the clause has ended. More commonly, this function would be written more succinctly as follows, using the built in booleans, `True` and `False`:

# +
def is_even(x):
    # Return True if x is even, otherwise return False
    return x % 2 == 0

is_even(3)
# -

# ## Coding with Style

# Most languages have a few different styles for writing code. In Java, for example, variables and methods typically use the camelCaseNaming convention where classes use AllUpperCaseNames. There have been great debates over things like where to put the curly braces ({}) in statements like if, for, and while and tabs versus spaces for indentation. 
#
# To solve most of these discrepancies, Python has a dedicated, community driven style guide known as PEP8 [https://www.python.org/dev/peps/pep-0008/]. The goal of this guide is to have consistent styling across all code written in Python so promote readability and ease of use. Unless your company has its own style guide, it is best to adhere to PEP8 as well as you can. Below I will demonstrate a quick example script that should over a lot of the most common elements. It's okay if some of the code presented below is unfamiliar. All of it will be covered in later chapters.

# +
# Import each module on its own line
# Avoid doing import lib1, lib2
import os
import time
# Use explicit imports
# Avoid using from lib import * since you don't know what will be pulled
# in and unknown functions could overwrite your own (known as shadowing)
from math import cos, sin 

my_str = "All python code lines should have a maximum line length of 79 " \
            "chars unless a longer line length is agreed upon " \
            "by the project team"

# One blank line above functions
def my_function(my_arg, my_kwarg=False):
    
    """
    All comments and doc strings should have a maximum line length of 72
    characters.
    
    Function/method names should use the snake_case style.
    
    Indentation should be 4 spaces unless otherwise dictated.
    Most editors can be configured (and some are by default) to treat
    4 spaces as a tab and insert them when hitting the tab key and
    removing them as one when backspacing over them.
    """
    my_variable = "Variables should also use the snake case style"

# All comments and doc strings should have a maximum line length of 72
x = 2  # End of line comments should be 2 spaces, a #, then space (__#_)

# In Python 3.5 and later, type hinting can be used to help
# IDEs determine auto completion and increase readablity
from typing import List, Union
def typed_function(x: int, my_int_list: List[int], 
                   multityped_arg: Union[int, str], 
                   typed_kwarg: bool=False) -> bool:
    my_typed_var: bool = typed_function(1, [2, 3], "test", True)
    if my_typed_var:
        return False
    else:
        for i in my_int_list:
            # No parenthesis are required in if statements
            # except to resolve order of operations
            if type(multityped_arg) == int and i == 2:
                return 2
            elif type(multityped_arg) == str and i == 3:
                return "3"
            else:
                return 10


# Two blank lines above and below classes
class MyClass:
    
    # Class names use the UpperCaseNaming style
    def __init__(self, arg1):
        self.arg1 = arg1
        
    # One line between functions
    def do_not_do_this(self, arg2):
        # Do NOT create new arguments outside of __init__
        # unless you really need to or the setup method
        # is only ever called from __init__.
        # Declare them as None if you don't want to set them immedietly.
        self.arg2 = arg2  # Do not do this

        
class MyClass2(MyClass):  # Only use parenthesis when inheriting
    pass


# -



StarcoderdataJupyterScriptsDedupFiltered