#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Felix Muzny
9/27/2022
DS 2000
Lecture 6 - while loops (finish), looping through files

Now playing:
    - "The Wake", a-ha
    - "Back in Black", AC/DC
    
We'll start lecture at ~9:52 to give time for folks who join right at 9:50

Logistics:
    - Quiz 3 is *already out*
        - due on Friday at 9:50am
    
    - Homework 3 is already available
        - again, you already have all the tools that you need for this
        homework — we do not expect you to use any of the material from
        this week on HW 3
  
    - no need to fill out a remote attendance form. :)
    
 Three ways to participate (please do one of these!)
 1) via the PollEverywhere website: https://pollev.com/muzny
 2) via text: text "muzny" to the number 22333 to join the session
 3) via Poll Everywhere app (available for iOS or Android)
    
Warm-up 0 - how are you doing?
---
A. great!
B. tired!
C. overwhelmed!
D. curious!
E. something else!

Not being overwhelmed with this course:
    - read through the homework early
    - if you are working on a problem and get stuck, leave


Warm-up 0.2 - what happens?
---
"""
import random 

# roll a die
die = random.randint(1, 6)
die = 4
print("die value", die)

# it's common to want to write
# die == 1 or 2
# but python translates this to:
# die == 1 or bool(2)
# die == 1 or True
if die == 1 or die == 2:
    print("so low!")
else:
    print("not so low")
    
print()
"""
Let's say that a _4_ was rolled:

A. so low!
B. not so low
C. error    
    
Summary:
    - when using and/or, python will always
    translate the expression to the left and right
    to boolean values
    - extra explicit about comparisons
    - bool(0) is the ONLY int that will be False



Warm-up 1 - while loops 1
---
What will happen with the following while loop?
"""
# 1) initialize the important values
# (what we'll test)
count = 10

# 2) test
while count <= 10:
    print(count)
    
    # 3) update the variables we're using to determine
    # repetitions
    count = count + 1

print("end while 1")
print()
"""
A. prints 1 - 10
B. prints 10
C. prints 10 forever
D. Nothing
E. Error


Warm-up 2 - while loops 2
---
Fill in the following code so that the while loop prompts
the user for an answer until they type "end"

"""

print("while 2")
# dummy value to make the loop start
answer = "otter"
# if we wanted this to be case insensitive
while answer.lower() != "end":
    answer = input("Response (end to stop)? ")
    
print("all done!")
print()


"""
Fun tid-bits
---

In python, we have a shorthand for writing down:

    x = x + 1
    
Instead, we write:
    
    x += 1
    
Similarly, x = x + 5 becomes x += 5.

We can also do this with the - operator:
    x = x - 1
    
Becomes: 
    x -= 1
"""



"""
While loops: what we rememember
---
    - run code until the boolean exp becomes False
    - while boolean exp:
        - code to be repeated gets indented "inside" the loop
    - we can use while loops when we know how many repetitions
    we want (I want 5 repetitions)
    - we can use while loops when we don't know how many repetitions
    we want (roll a die until a certain value)
"""


"""
While loops + plotting
----
We can *absolutely* combine plotting with while loops.
For instance, let's plot the guesses that the user was making in our
hotcold.py program.

We'll  save this program as hotcold_plots.py
"""



"""
While loops: common patterns
---
(https://muzny.github.io/csci1200-notes/06/2/common_while_uses.html)
(https://muzny.github.io/csci1200-notes/06/3/while_accumulator.html)

"until X"

"up to a number/repeat X times"

"accumulator"
"""
print("until x")
# ask the user if they like cats until they say yes
answer = "otter"
# if we wanted this to be case insensitive
while answer.lower() != "yes":
    answer = input("do you like cats (yes to stop)? ")

print()


print("repeat X times")
# print out a random number from 1 to 3 five times
count = 0
# because we start at 0, <
while count < 5:
    print(random.randint(1, 3))
    count += 1
print()


print("accumulator")
# count the number of 1s in five random  numbers from 1 to 3
count = 0
# 1) initialize an accumulator variable
num_ones = 0

while count < 5:
    rand_num = random.randint(1, 3)
    print(rand_num)
    # 2) did I see the thing that I'm counting?
    if rand_num == 1:
        num_ones += 1
    
    count += 1
    
# 3) after the loop, the accumulator variable has the answer
print("num of ones:", num_ones)
print()


"""
Nested loops: what's the story
---
Typically used when you have a task that needs repeating and the
*task itself* involves repetitions.

For example, suppose that I want to count from 1 - 3 ten times.

inner loop: task itself (count from 1 - 3)
    
outer loop: repeat 10 times

"""

# example, note that both loops have all of the three 
# required parts of a while loop.

print("nested loop!")
# A) init. tracker variable
outer_count = 0
# B) test (have I dont this 10 times?)
while outer_count < 10:
    # 1) init. tracker variable
    count = 0
    # 2) test
    while count < 3:
        print(count +  1)
        # 3) update
        count += 1
        
    print()
    # C) update 
    outer_count += 1
print()


"""
Reading files with while loops 1
---
While loops let us repeat an action as many times as we'd like to.
    
Take a look at our first data file for today:
    - distances.txt
    
It's not immediately obvious what we would want the condition on
our while loop to be if we used a loop to go through this file...

"""

print("Reading from files")
file = open("distances.txt", "r")
# 1) initialize a tracker variable?
line = file.readline()
# 2) does this line exist?
# str.strip() function removes whitespace
while line.strip() != "":
    print(line)
    # 3) update
    line = file.readline()

file.close()
print()

"""
Data structures: lists
-----
data structure - an abstraction for holding multiple different 
values in a programming environment
"""
print("list examples")
# create an empty list
numbers = []

# test the size of a list
print(len(numbers))  # 0

# add something to the end of a list
# no return value
numbers.append(17)
numbers.append(-2)

print(numbers)  # [17, -2]
print(len(numbers))  # 2

# create a non-empty list
animals = ["cat", "dog", "parrot"]
print(animals)
print()


"""
Reading files with while loops 2
---
Getting a list of strings out of the file:

    file = open("distances.txt", "r")
    # with an s
    lines = file.readlines()
    file.close()
    
"""
print("while loop over a file with a list")
file = open("distances.txt", "r")
# with an s
lines = file.readlines()
print(lines)
file.close()

# access a specific item in a list
# 0 is the first item
# accessing by index
print("first line by index", lines[0])


# iterate over the values in a list
element_number = 0
while element_number < len(lines):
    print(lines[element_number])
    element_number += 1

print()

"""
Getting a list from a string: str.split()
-----

Say I have a string, for instance, the first words
of Middlemarch by George Eliot:
"""
print("split examples")
fancy_text = "Who that cares much to know the history of man"

# If I want a list from this string, I use the str.split() function:
    
words = fancy_text.split()
print(words)

# I could also split on the letter "a" to demonstrate what python
# is doing—it is using the "splitter" string as the thing to delete 
# and separate the original string into smaller substrings.

by_as = fancy_text.split("a")
print(by_as)


# We'll start from here on Friday!


"""
Example problem:
---

Write a program, distance.py, that reads the data from the file distances.txt and 
graphs it accordingly on a scatter plot.
"""

"""
for loops 1: syntax
---


"""

"""
General for loops syntax 1
---

"""

"""
Example problem, updated:
---

Write a program, distance.py, that reads the data from the file 
distances_complex.txt and graphs it accordingly on a scatter plot.
Color days that were a run with one color and days that were a bike ride 
a different color.
"""


"""
Next time:
    - more for loops!
    - for loops with indexes
    - all the ways to iterate over a list
    
"""





