Unexpected junk after else? - fortran

I am new to Fortran (I mean I started 5 mins ago) and i have been messing around and I know how to do prints start/end programs and the if part of the if statement. The problem I am having, though, is with the else part. It keeps coming up with the error:
ELSE() print *, "x did not = 1"
1
Error: Unexpected junk after ELSE statement at (1)
Here is my code:
program hello
x = 1
IF(x==1) print *, "Hello"
IF(x==1) x=2
IF(x==1) print *, "Oh it didnt work..."
ELSE() print *, "x did not = 1 yay it worked"
end program hello

The correct structure for your example code should be similar to:
program hello
x = 1
if( x == 1) print *, 'hello'
if( x == 1) x=2
25 if( x == 1) then
print *, "oh it didn't work..."
else
print *, "x did not = 1 yay it worked"
endif
end program hello
Notice that the if statement in line 25 is followed by the 'then' keyword and you options are divided by the else statement.
Also the line number is not necessary. I just used it here so I could reference the line in my answer.

Related

Repeat a function every 5 times a loop runs

Is there a way to repeat a single function in a while loop one in every 5 times the loop runs? I am trying to create a bot to help me with my Latin revision but I don't want the option to close the program to crop up every time I answer a question, it would be better if it only happened 1 out of 10 times.
import random
exit = "no"
print "welcome to latin learner v1"
wordtype = raw_input("what would you like to learn (nouns verbs everything)")
if wordtype == "nouns":
declension = raw_input("declension 1-5")
if declension == "1":
while "no" in exit:
wordno = random.randint(1,30)
noun1L = ["ancilla","aqua","cena","copiae","cura","dea","domina","epistula","femina","filia","hora","ianua","insula","ira","nauta","patria","pecunia","poena","porta","puella","regina","Roma","silva","taberna","terra","turba","via","victoria","villa","vita"]
answer = raw_input(noun1L[wordno])
noun1E = ["slave-girl" or"slave-woman","water","dinner" or "meal","forces" or "troops","care" or "worry","goddess","mistress","letter","woman","daughter","hour","door","island" or "block of flats","anger","sailor","country" or "homeland","money","punishment","gate","girl","queen","Rome","wood","shop" or "inn","ground" or "land" or "country","crowd","street" or "road" or "way","victory","house" or "country villa","life"]
if noun1E[wordno] == answer:
print "correct"
else:
print "incorrect"
print noun1E[wordno]
for i in range[1,5]:
exit = raw_input("would you like to quit (yes/no)")
To solve your issue, we can add a question counter and use the modulus operator (%) to trigger the exit option on every fifth question.
However, there are some other problems to address. For example, this:
,"dinner" or "meal",
is just wishful thinking -- it doesn't work that way. We can turn this into a list of possible answers. Next, whenever we have parallel arrays like noun1L and noun1E, it usually means we're missing a data structure. Finally, don't store the data in the code, separate them.
Here's my rework of your code addressing the above issues:
import random
noun1 = {
"ancilla": ["slave-girl", "slave-woman"],
"aqua": ["water"],
"cena": ["dinner", "meal"],
"copiae": ["forces", "troops"],
"cura": ["care", "worry"],
"dea": ["goddess"],
"domina": ["mistress"],
"epistula": ["letter"],
"femina": ["woman"],
"filia": ["daughter"],
"hora": ["hour"],
"ianua": ["door"],
"insula": ["island", "block of flats"],
"ira": ["anger"],
"nauta": ["sailor"],
"patria": ["country", "homeland"],
"pecunia": ["money"],
"poena": ["punishment"],
"porta": ["gate"],
"puella": ["girl"],
"regina": ["queen"],
"Roma": ["Rome"],
"silva": ["wood"],
"taberna": ["shop", "inn"],
"terra": ["ground", "land", "country"],
"turba": ["crowd"],
"via": ["street", "road", "way"],
"victoria": ["victory"],
"villa": ["house", "country villa"],
"vita": ["life"],
}
print("Welcome to Latin Learner v1")
wordtype = raw_input("What would you like to learn (nouns verbs everything): ")
if wordtype == "nouns" or wordtype == "everything":
declension = raw_input("Declension 1-5: ")
if declension == "1":
count = 1
while True:
word = random.choice(list(noun1))
answer = raw_input(word +": ")
if answer.lower() in noun1[word]:
print("Correct.")
else:
print("Incorrect: " + ", ".join(noun1[word]))
if count % 5 == 0:
answer = raw_input("would you like to quit (yes/no): ")
if "y" in answer.lower():
break
count += 1

Python: Trying to loop through a string to find matching characters

I am trying to create a simple "guess the word" game in Python. My output is something like:
String: _____ _____
Guess a word: 'e'
String:_e__o __e_e
Guess a word: 'h'
(and so on)
String: hello there
I have a function to do this, and within this function I have this code:
def guessing(word):
count = 0
blanks = "_" * len(word)
letters_used = "" #empty string
while count<len(word):
guess = raw_input("Guess a letter:")
blanks = list(blanks)
#Checks if guesses are valid
if len(guess) != 1:
print "Please guess only one letter at a time."
elif guess not in ("abcdefghijklmnopqrstuvwxyz "):
print "Please only guess letters!"
#Checks if guess is found in word
if guess in word and guess not in letters_used:
x = word.index(guess)
for x in blanks:
blanks[x] = guess
letters_used += guess
print ("".join(blanks))
print "Number of misses remaining:", len(word)-counter
print "There are", str(word.count(guess)) + str(guess)
guess is the raw input I get from the user for a guess, and letters_used is just a collection of guesses that the user has already input. What I'm trying to do is loop through blanks based on the word.index(guess). Unfortunately, this returns:
Guess a letter: e
e___
Yes, there are 1e
Help would be much appreciated!
Your code was almost correct. There were few mistakes which I have corrected:
def find_all(needle, haystack):
"""
Finds all occurances of the string `needle` in the string `haystack`
To be invoked like this - `list(find_all('l', 'hello'))` => #[2, 3]
"""
start = 0
while True:
start = haystack.find(needle, start)
if start == -1: return
yield start
start += 1
def guessing(word):
letters_uncovered_count = 0
blanks = "_" * len(word)
blanks = list(blanks)
letters_used = ""
while letters_uncovered_count < len(word):
guess = raw_input("Guess a letter:")
#Checks if guesses are valid
if len(guess) != 1:
print "Please guess only one letter at a time."
elif guess not in ("abcdefghijklmnopqrstuvwxyz"):
print "Please only guess letters!"
if guess in letters_used:
print("This character has already been guessed correctly before!")
continue
#Checks if guess is found in word
if guess in word:
guess_positions = list(find_all(guess, word))
for guess_position in guess_positions:
blanks[x] = guess
letters_uncovered_count += 1
letters_used += guess
print ("".join(blanks))
print "Number of misses remaining:", len(word)-letters_uncovered_count
print "There are", str(word.count(guess)) + str(guess)
else:
print("Wrong guess! Try again!")

How to invoke a program and pass it standard input

How do I invoke a program and pass it standard input? Hypothetical example in Bash:
(echo abc; echo abba) | tr b B
Note that:
I don't have the input in a string (I'm generating it as I iterate)
I don't know how long input is
The input may span multiple lines, as in this example
I've written this in 19 other languages already, the way I usually approach it is to get a file descriptor for the program's standard input, and then write to the file descriptor the same way I would write to standard output.
What I've tried so far: Based on Invoke external program and pass arguments I tried passing it to echo and using the shell to handle the piping. This doesn't work if my input has single quotes in it, and it doesn't work if I don't have my input in a string (which I don't)
Here is my code, currently trying to pull it off by calculating the string that will be printed (it fails right now).
As for single quotation, how about inserting the escape character (\) before each quotation mark (')...? It seems to be working somehow for the "minimal" example:
module utils
implicit none
contains
function esc( inp ) result( ret )
character(*), intent(in) :: inp
character(:), allocatable :: ret
integer :: i
ret = ""
do i = 1, len_trim( inp )
if ( inp( i:i ) == "'" ) then
ret = ret // "\'"
else
ret = ret // inp( i:i )
endif
enddo
endfunction
endmodule
program test
use utils
implicit none
character(100) :: str1, str2
integer i
call getcwd( str1 ) !! to test a directory name containing single quotes
str2 = "ab'ba"
print *, "trim(str1) = ", trim( str1 )
print *, "trim(str2) = ", trim( str2 )
print *
print *, "esc(str1) = ", esc( str1 )
print *, "esc(str2) = ", esc( str2 )
print *
print *, "using raw str1:"
call system( "echo " // trim(str1) // " | tr b B" )
print *
print *, "using raw str2:"
call system( "echo " // trim(str2) // " | tr b B" ) !! error
print *
print *, "using esc( str1 ):"
call system( "echo " // esc(str1) // " | tr b B" )
print *
print *, "using esc( str2 ):"
call system( "echo " // esc(str2) // " | tr b B" )
print *
print *, "using esc( str1 ) and esc( str2 ):"
call system( "(echo " // esc(str1) // "; echo " // esc(str2) // ") | tr b B" )
! pbcopy (copy to pasteboard; mac-only)
! call system( "(echo " // esc(str1) // "; echo " // esc(str2) // ") | pbcopy" )
endprogram
If we run the above program in the directory /foo/baa/x\'b\'z, we obtain
trim(str1) = /foo/baa/x'b'y
trim(str2) = ab'ba
esc(str1) = /foo/baa/x\'b\'y
esc(str2) = ab\'ba
using raw str1:
/foo/baa/xBy
using raw str2:
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
using esc( str1 ):
/foo/baa/x'B'y
using esc( str2 ):
aB'Ba
using esc( str1 ) and esc( str2 ):
/foo/baa/x'B'y
aB'Ba
This is what I mean by a minimal example.
call execute_command_line("(echo ""hexxo world"";echo abba)|tr x l")
end
hello world
abba
Is this not doing exactly what you ask, invoking tr and passing standard input?

Multiple Errors in Hangman program

I've been teaching my self to program in python lately and decided to make this game. I have been successful for the majority of it except for a few things
When an incorrect letter is inputted, the letter is appended to the wrong letter array for as many spots in the gamespace array that the userletter does equal.Example: if I type in "the" for the wordtarget, I get t, h and e printed 2 times into wrong letter array. No matter what the letter gets out into wrong letter array
Code:
wordTarget = raw_input("enter word here: ").lower ()
gameSpace = ["_"] * Len(wordTarget)
wrongLetter = []
def main():
for x in range(0, len(wordTarget)):
while (gameSpace[x] != wordTarget[x]):
getLetter()
for i in range(0,len(wordTarget)):
if (wordTarget[i] == userLetter):
gameSpace[i] = userLetter
elif (wordTarget[i] != userLetter):
print "letter is incorrect, try again"
wrongLetter.append(userLetter)
print ("Incorrect Letters: %s" % wrongLetter)
print ("Correct Letters: %s" % gameSpace)
if (gameSpace == wordTarget):
print "Congratulations! You won"
main()
I'm guessing the problem lies with the for loops I'm running and the way I'm checking for right answer but can't figure it out.
The loop checking the letter seems to be your issue. Try replacing it with:
position = 0
ptr = wordTarget.find(userLetter, position)
while ptr != -1:
gameSpace[ptr] = userLetter
position = ptr + 1
ptr = wordTarget.find(userLetter, position)
if position == 0: # no match ever found
print "letter is incorrect, try again"
wrongLetter.append(userLetter)
Also replace the original for loop with while ("".join(gameSpace) != wordTarget):, and you should be good to go.

Printing out values from a function

Ok so the issue with my program is that for some reason when I run it the variables at the bottom come out as "None" instead of the count of the amount of ATG's in the original strings of HumanDNA, MouseDNA, and UnknownDNA. I couldn't add the part where i define these DNA's because of their length and was difficult for me to add it. How can I change it so instead it outputs the amount of times the substring is found in the original string as a variable that is outside the function and can output it in the format I have at the bottom.
def countCodon(string, substring):
i = string.find(substring)
def compareDNA(string1, string2):
string1 = raw_input("Enter string 1: ")
string2 = raw_input("Enter string 2: ")
Hamming = 0
for ch1, ch2 in zip(string1, string2):
if ch1 != ch2:
Hamming += 1
l = len(string1)
similarity_score = ((l - Hamming)/(l))
print similarity_score
HD = countCodon(humanDNA, "ATG")
MD = countCodon(mouseDNA, "ATG")
UD = countCodon(unknownDNA, "ATG")
print "Mouse: ", HD
print "Human: ", MD
print "Unknown: ", UD
MU = compareDNA(mouseDNA, unknownDNA)
HU = compareDNA(humanDNA, unknownDNA)
if MU != HU and MU > HU:
print "mouse"
elif MU != HU and MU < HU:
print "human"
elif MU == HU:
print "identity cannot be determined"
EDIT: Added the messed up part of the second function running into a similar problem.
countCodon() has no return value so HD = None
Moreover from https://docs.python.org/2/library/string.html
string.find(s, sub[, start[, end]])
Return the lowest index in s where the substring sub is found such that sub is wholly contained in s[start:end]. Return -1 on failure. Defaults for start and end and interpretation of negative values is the same as for slices.
So countCodon() is giving you the index where the string "ATG" first appears, not the number of times it is present.