Python Using Databases in Python Our Diary App Switching It Up

Sahar Nasiri
Sahar Nasiri
7,454 Points

./diary.py

When I run ./diary.py, I get "No such file or directory" error! What is the problem?

7 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 59,892 Points

Running ./diary.py looks in the current directory for the file diary.py. You can list the directory using ls to see if it is present.

Sahar Nasiri
Sahar Nasiri
7,454 Points

I did and there is an executable file named diary.py, but I still get the same error when I run ./diary.py!

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

Ok. It could be a few other reasons. Try

python daisy.py

Or

Verify the file is executable. Try

ls -l

to verify the file is executable. The output should show an "X" in the listing such as "rwx".

Check that the file has the correct shebang path "#!" as the first line.

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

Hey Sahar Nasiri, I think I have it solved. In short, the shebang path is incorrect.

When running ./diary.pythe shebang value at the top of the file is executed. In this case, the value in line 1 incorrectly points to a non-existent location for python3. Correcting this path allows execution:

# Try current file
treehouse:~/workspace$ ./diary.py 
: No such file or directory

# Check shebang
treehouse:~/workspace$ head -1 diary.py 
#!/usr/bin/env python3

# Where is python3 really coming from
treehouse:~/workspace$ which python3 
/usr/local/pyenv/shims/python3

# Create new file with correct shebang
# Add shebang
treehouse:~/workspace$ echo -n '#!' > diary2.py
# Add path to python3
treehouse:~/workspace$ which python3 >> diary2.py
# Add lnes 2 through end of diary.py
treehouse:~/workspace$ tail -n+2 diary.py >> diary2.py 

# Compare diary versions
treehouse:~/workspace$ diff diary.py diary2.py
1c1 
< #!/usr/bin/env python3 
--- 
> #!/usr/local/pyenv/shims/python3 

# Add execution permissions
treehouse:~/workspace$ chmod +x diary2.py

# Run file
treehouse:~/workspace$ ./diary2.py 
Enter 'q' to quit. 
a) Add an entry 
v) View previous entries 
s) search entries for a string 
Actions: q 
treehouse:~/workspace$
Alex Crump-Haill
Alex Crump-Haill
5,943 Points

Hi Chris, can you explain what calling 'ls' does, where it comes from and why it is useful? Thanks

Anders Axelsen
Anders Axelsen
3,470 Points

Hi there, Chris.

I have been struggling with this for some time now. I was wondering if there is a solution. :-)

My first shebang: #!/usr/local/pyenv/shims/python3

My second shebang (formatted as in video): #!/usr/local/pyenv/shims python3

  • Here, I got Permission denied and was led to believe a chmod +x diary2.py would solve the issue. It didn't happen.

Snapshot: https://w.trhou.se/ogiefaq98o

Commands from console:

# which python:
treehouse:~/workspace$ which python3                                                                               
/usr/local/pyenv/shims/python3 
treehouse:~/workspace$ ls -1                                                         
diary2.py                                                                            
diary.db                                                                             
diary.py                                                                             
students.db                                                                          
Students.db                                                                          
students.py                                                                          
treehouse:~/workspace$ ./diary2.py      
# result from first shebang:                                             
bash: ./diary2.py: /usr/local/pyenv/shims/python3^M: bad interpreter: No such file or
 directory                                                                           
treehouse:~/workspace$ ./diary2.py         
# result from second shebang:                                          
bash: ./diary2.py: /usr/local/pyenv/shims: bad interpreter: Permission denied        
treehouse:~/workspace$ chmod +x diary2.py                                            
treehouse:~/workspace$ ./diary2.py                                                   
bash: ./diary2.py: /usr/local/pyenv/shims: bad interpreter: Permission denied
Sahar Nasiri
Sahar Nasiri
7,454 Points

I did all these before and diary.p is an executable file and I runs when I write python diary.py, but still I cannot run it with ./diary.py command! :(

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

Ok a few more questions:

  • if you're using workspaces, can you make a snapshot (icon upper right), and post the link to it?
  • If local, which OS and command shell are you using?
Sahar Nasiri
Sahar Nasiri
7,454 Points

Chris Freeman Thanks, it worked with diary2.py. But When I update the python path above diary.py I still get bash: ./diary.py: /usr/local/pyenv/shims/python3^M: bad interpreter: No such file or directory this error! Why can't I fix diary.py?

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

It looks like it doesn't like something in the shebang line. Can you post the forest few lines of the diary file? Plus also post the output of the command "which python3".

Sahar Nasiri
Sahar Nasiri
7,454 Points

When I type which python I get : /usr/local/pyenv/shims/python

Here's diary code:

#!/usr/local/pyenv/shims/python3

import datetime
from collections import OrderedDict
import os
import sys

from peewee import *

db = SqliteDatabase('diary.db')

class Entry(Model):
    content = TextField()#char field has to have length but we want this to be huge
    timestamp = DateTimeField(default=datetime.datetime.now) # If whe wrote now() we would get the fisrt time that the script had been ran
    class Meta:
        database = db


def initialize():
    """ Create the database and the table if they don't exist"""
    db.connect()
    db.create_tables([Entry], safe=True)

def clear():
    os.system('cls' if os.name == 'nt' else 'clear') # If we are on windows it calls 'cls' and if we are on Mac or Linux it calls 'clear'.


def menu_loop():
    """Show the menu"""
    choice = None
    while choice != 'q':
        clear()
        print("Enter 'q' to quit.")

        for key, value in menu.items():
            print('{}) {}'.format(key, value.__doc__))
        choice = input('Actions: ').lower().strip()
        if choice in menu:
            clear()
            menu[choice]()


def add_entry():
    """Add an entry"""
    print("Enter your entry. Press ctrl+d when you finished.")
    data = sys.stdin.read().strip()
    if data:
        if input('Save entry?[Yn]').lower() != 'n':
            Entry.create(content=data)
            print('Saved Successfully!')


def view_entries(search_quary=None):
    """View previous entries"""
    entries = Entry.select().order_by(Entry.timestamp.desc())

    if search_quary:
        entries = entries.where(Entry.content.contains(search_quary))

    for entry in entries:
        timestamp = entry.timestamp.strftime('%A %B %d, %Y %I:%M%p')
        clear()
        print(timestamp)
        print('='*len(timestamp))
        print(entry.content)
        print('\n\n'+'='*len(timestamp))
        print('N) next entry')
        print('d) delete entry')
        print('q) return to main menu')

        next_action = input('Action: [Ndq]').lower().strip()
        if next_action == 'q':
            break
        elif next_action == 'd':
            delete_entry(entry)

def search_entries():
    """search entries for a string"""
    view_entries(input('Search_quary: '))

def delete_entry(entry):
    """Delete an entry"""
    if input('Are you sure? [yN]').lower().strip() == 'y':
        entry.delete_instance()
        print('Entry deleted!')

menu = OrderedDict([
    ('a', add_entry),
    ('v', view_entries),
    ('s', search_entries)
])  

if __name__ == '__main__':
    initialize()
    menu_loop()
Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

Sorry didn't see your comment at the top. And what is the output of the command "which python3".

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

OK. Workspace environments change slightly over time. You now have the solution. Make the shebang match the output of the which command by remove the tailing "3"

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

Why diary.py is different from diary2.py is confusing. There must be something else different. But if adjusting the shebang works, call it good! :grin:

Sahar Nasiri
Sahar Nasiri
7,454 Points

:( I did remove the "3" but still get this: bash: ./diary.py: /usr/local/pyenv/shims/python^M: bad interpreter: No such file or directory

Chris Freeman
Chris Freeman
Treehouse Moderator 59,892 Points

This is very strange non-deterministic behavior (very uncomputer like). If diary2.py runs, but not diary.py and there is no other differences between the two (check by running diff diary.py diary2.py), then I suggest overwriting diary.py with the working diary2.py using $ mv diary2.py diary.py.

Sahar Nasiri
Sahar Nasiri
7,454 Points

Finally it fixed :))! Thanks alot :))